string.h

string .h 头文件定义了一个变量类型、一个宏和各种操作字符数组的函数。

  • size_t 这是无符号整数类型,它是 sizeof 关键字的结果。

  • NULL 这个宏是一个空指针常量的值。

    strcpy

  1. char *strcpy(char *dest, const char *src); // 返回dest字符串的起始地址。

如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况,会覆盖掉其他内存区域。它在把字符串 b 拷贝到字符串 a 的时候,会在拷贝的 a 字符串的末尾加上一个 \0 结束标志。

strncpy

  1. char *strncpy(char *dest, const char *src, size_t n)

strncpy会将参数src字符串拷贝前n个字符至参数dest所指的地址。返回值是返回参数dest的字符串起始地址。

  1. strncpy(dest, src, sizeof(dest));
  2. dest[sizeof(dest)-1] = '\0';

务必要把 dest 的最后一个字节手工设置为 \0 ,否则不会自动加 \0 。strncpy 在 src 的长度小于 dest 时,对剩余的字节填 \0 。或者 src 不足 n 时就有 \0 字符,那么会对 dest 之后的字符全部填 \0 .

strcat,strncat

  1. char *strncat(char *dest, const char *src, size_t n)

把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,直到 n 字符长度为止。strcat 没有第三个参数不安全。两个函数遇到 \0 结束,实际上字符串的函数(str 开头)都会以 \0 作为目标字符串接受的标志。

strcmp,strncmp

  1. int strncmp(const char *str1, const char *str2, size_t n)

如果返回值 < 0,则表示 str1 小于 str2。如果返回值 > 0,则表示 str2 小于 str1。如果返回值 = 0,则表示 str1 等于 str2。

strchr,strrchr

  1. char *strchr(const char *str, int c)
  2. char *strrchr(const char *str, int c)

该函数返回 str 中第一次出现字符 c 的位置。如果未找到该值,则函数返回一个空指针。
该函数返回 str 中最后一次出现字符 c 的位置。如果未找到该值,则函数返回一个空指针。

strstr

  1. char *strstr(const char *haystack, const char *needle)

该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。可以使用 KMP 算法等。

strtok

  1. char *strtok(char *str, const char *delim)

分解字符串 str 为一组字符串,delim 为分隔符。该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

第一次调用传的是需要拆分的字符串,之后想要继续拆分传 NULL 即可,还有分割处理后原字符串 str 会变,变成第一个子字符串。相当于将分隔符替换成 \0 。

使用该函数进行字符串分割时,会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。第一次分割之后,原字符串str是分割完成之后的第一个字符串,剩余的字符串存储在一个静态变量中,因此多线程同时访问该静态变量时,则会出现错误。

strtok_s是windows下的一个分割字符串安全函数,strtok_s函数是linux下分割字符串的安全函数。函数将剩余的字符串存储在buf变量中,而不是静态变量

stdio.h

sprintf

  1. int sprintf(char *str, const char *format, ...)

组包函数,将多个变量组包放在一个内存区域中,成功则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。该函数是在标准 io 库中的函数。

  1. #include <stdio.h>
  2. #include <math.h>
  3. int main()
  4. {
  5. char str[80];
  6. sprintf(str, "Pi 的值 = %f", M_PI);
  7. puts(str);
  8. return(0);
  9. }

sscanf

  1. int sscanf(const char *str, const char *format, ...)

拆包函数,从一个字符串中拆出数据放在变量中,如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。使用这个函数前提是知道指定字符串的样子。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. int main()
  5. {
  6. int day, year;
  7. char weekday[20], month[20], dtm[100];
  8. strcpy( dtm, "Saturday March 25 1989" );
  9. sscanf( dtm, "%s %s %d %d", weekday, month, &day, &year );
  10. printf("%s %d, %d = %s\n", month, day, year, weekday );
  11. return(0);
  12. }

sscanf 的正则性匹配

sscanf("hello, world", "%*s%s", buf); , 结果为world %s 会将第一个匹配到的 %s 过滤掉,直到空格或者制表符,也可以过滤 %d 数字。

sscanf("123456 ", "%4s", buf); ,结果为:1234,读取指定宽度。

sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf); , 结果为:123456abcdedf,贪婪性地匹配任意字符。这个正则是从字符串开头开始匹配的,如果开头匹配失败就会匹配为空。

sscanf("123456 abcdedf", "%[^ ]", buf); ,结果为:123456,%[^ ] 匹配非 的任意字符贪婪性。

%[aBc] 匹配aBc中一员贪婪性从开头开始匹配,%*[a-z] 读取除了 a-z 之外的所有字符,这个也是从头开始忽略

stdlib.h 下的 atof,atoi,atol,atoll

将字符串变为数值类型,遇到空白的字符或者其他不是数字的字符会直接忽略,这个系列的函数经常会失败,且只支持十进制,对一个字符串只进行一次解析。

stdint.h 下的 strtoX 系列函数

这个系列函数支持捕捉错误,支持多次解析同一个字符串。

  1. char const *start = "1 200000000000 3 -4";
  2. char *end;
  3. while(1) {
  4. errno = 0;
  5. const long i = strtol(start, &end, 10);
  6. if(start === end) {
  7. break;
  8. }
  9. printf("'%.*s'\t ===> %ld.", (int)(end - start), start, i);
  10. start = end
  11. }

每次解析完成之后 strtol 会对 end 进行赋值,值为第二个开始解析字符的指针。