String.h

`'''string.h'''`是C标准库的一个头文件，其中包含了宏（宏）定义、常量以及函数和类型的声明，涉及的内容除了字符串处理之外，还包括大量的内存处理函数；因此，`string.h`这个命名是不恰当的。

在`string.h`中定义的函数十分常用，作为C标准库的一部分，它们被强制要求可以在任何支持C语言的平台上运行。但是，部分函数存在一些安全隐患，例如缓存溢出等，导致程序员宁愿使用一些更安全的函数而放弃一定的可移植性。同时，这些字符串函数只能处理ASCII字符集或兼容ASCII的字符集，如ISO-8859-1；在处理存在多字节字符的字符集，如UTF-8时，会产生一个警告，指出对字符串“长度”的计算是以字节而不是以Unicode字符为单位。非ASCII兼容字符集的字符串处理函数一般位于`wchar.h`中。

## 常量和类型

名称｜说明

`NULL`｜表示空指针常量的宏，即表示一个不指向任何有效内存单元地址的指针常量。

`size_t`｜无符号整型，被用于`sizeof`运算符的返回值类型。

## 函数

名称｜说明

`void *memcpy(void *dest, const void *src, size_t n);`｜将n字节长的内容从一个内存地址复制到另一个地址；如果两个地址存在重叠，则最终行为未定义

`void *memmove(void *dest, const void *src, size_t n);`｜将n字节长的内容从一个内存地址复制到另一个地址；与`memcpy`不同的是它可以正确作用于两个存在重叠的地址

`void *memchr(const void *s, char c, size_t n);`｜在从s开始的n个字节内查找c第一次出现的地址并返回，若未找到则返回NULL

`int memcmp(const void *s1, const void *s2, size_t n);`｜对从两个内存地址开始的n个字符进行比较

`void *memset(void *, int, size_t);`｜用某种字节内容覆写一段内存空间

`char *strcat(char *dest, const char *src);`｜在字符串dest之后连接上src

`char *strncat(char *dest, const char *src, size_t n);`｜从src截取n个字符连接在字符串dest之后，返回dest字符串

`char *strchr(const char* str, int ch);`｜从字符串str头开始查找字符ch首次出现的位置

`char *strrchr(const char* str,int ch);`｜从字符串str尾开始查找字符ch首次出现的位置

`int strcmp(const char *, const char *);`｜基于字典顺序比较两个字符串

`int strncmp(const char *, const char *, size_t n);`｜基于字典顺序比较两个字符串，最多比较n个字节

`int strcoll(const char *, const char *);`｜基于当前区域设置的字符顺序比较两个字符串

`char *strcpy(char* str1, const char* str2);`｜将str2拷贝给str1

`char *strncpy(char* str1, const char* str2, size_t n);`｜截取str2的n个字符拷贝给str1

`char *strerror(int);`｜返回错误码对应的解释字符串，参见errno.h（非线程安全函数）

`size_t strlen(const char *);`｜返回一个字符串的长度

`size_t strspn(const char *s, const char *strCharSet);`｜从字符串s的起始处开始，寻找第一个不出现在strCharSet中的字符，返回其位置索引值。换句话说，返回从字符串s的起始位置的完全由strCharSet中的字符构成的子串的最大长度。strspn为string span的缩写。不支持多字节字符集。

`size_t strcspn(const char *s, const char *strCharSet);`｜从字符串s的起始处开始，寻找第一个出现在strCharSet中的字符，返回其位置索引值。换句话说，返回从字符串s的起始位置的完全由不属于strCharSet中的字符构成的子串的最大长度。strcspn为string complement span的缩写。不支持多字节字符集。

`char *strpbrk(const char *s, const char *breakset);`｜在字符串s中查找breakset中任意字符第一次出现的位置的指针值。strpbrk为string pointer break缩写。通常，breakset是分隔符的集合。不支持多字节字符集。

`char *strstr(const char *haystack, const char *needle);`｜在字符串haystack中查找字符串needle第一次出现的位置，heystack的长度必须长于needle

`char *strtok(char *strToken, const char *strDelimit );`｜将一个字符串strToken依据分界符（delimiter）分隔成一系列字串。此函数非线程安全，且不可重入；但MSVC实现时使用了thread-local static variable因而是线程安全的但仍然是不可重入，即在单线程中不能对两个源字符串交替调用该函数来分析token，应当对一个字符串分析完成后再处理别的字符串。

`size_t strxfrm(char *dest, const char *src, size_t n);`｜根据当前locale转换一个字符串为strcmp使用的内部格式

### ISO C扩展函数

名称｜说明｜标准

void、memccpy(void、dest, const void、src, int c, size_t n );｜在两块不重叠的内存地址间复制内容，直至复制了n字节或遇到内容为c的字节｜UNIX 98?

`void *mempcpy(void *dest, const void *src, size_t n);`｜`memcpy`的变体，返回写入的最后一个字节的地址指针｜GNU

`errno_t strcat_s(char *s1, size_t s1max, const char *s2);`｜`strcat`的变体，带边界检查｜ISO/IEC WDTR 24731

`errno_t strcpy_s(char *s1, size_t s1max, const char *s2);`｜`strcpy`的变体，带边界检查｜ISO/IEC WDTR 24731

`char *strdup(const char *);`｜将字符串的内容复制到一段新分配的内存空间｜POSIX；源于一个BSD扩展标准

`int strerror_r(int, char *, size_t);`｜将strerror的结果放入一段给定的内存缓冲，此函数是线程安全的｜POSIX:2001

`char *strerror_r(int, char *, size_t);`｜使用线程安全的方式返回strerror的结果。在必要的时候才使用给定的内存缓冲 (与POSIX中的定义不一致).｜GNU

`size_t strlcat(char *dest, const char *src, size_t n);`｜`strcat`的变体，带边界检查｜首先定义于OpenBSD，现在也可以在FreeBSD、Solaris、Mac OS X中找到

`size_t strlcpy(char *dest, const char *src, size_t n);`｜`strcpy`的变体，带边界检查｜首先定义于OpenBSD，现在也可以在FreeBSD、Solaris、Mac OS X中找到

`char *strsignal(int sig);`｜与`strerror`类似，返回有符号数`sig`对应的错误解释字符串（非线程安全函数）｜BSDs, Solaris, Linux

`char *strtok_r(char *, const char *, char **);`｜strtok的线程安全且可重入的版本｜POSIX