1、 字符串的初始化函数
void *memset(void *s, int c, size_t n);
返回值:s指向哪,返回的指针就指向哪
说明:memset
函数把s
所指的内存地址开始的n
个字节都填充为c
的值。通常c
的值为0,把一块内存区清零。例如定义char buf[10];
,如果它是全局变量或静态变量,则自动初始化为0(位于.bss
段),如果它是函数的局部变量,则初值不确定,可以用memset(buf, 0, 10)
清零,由malloc
分配的内存初值也是不确定的,也可以用memset
清零。
2、取字符串的长度
size_t strlen(const char *s);
返回值:字符串的长度
说明:返回的长度不包括'\0'
字符在内
3、拷贝字符串
char *strcpy(char *dest,const char *src);
说明:strcpy
在拷贝字符串时会把结尾的'\0'
也拷到dest
中,因此保证了dest
中是以'\0'
结尾的字符串。strcpy
只知道src
字符串的首地址,不知道长度,它会一直拷贝到'\0'
为止,所以dest
所指向的内存空间要足够大,否则有可能写越界。如果没有保证src
所指向的内存空间以'\0'
结尾,也有可能读越界。src
和dest
所指向的内存空间不能有重叠。
char *strcpy(char *dest,const char *src,size_t n);
说明:strncpy
的参数n
指定最多从src
中拷贝n
个字节到dest
中,换句话说,如果拷贝到'\0'
就结束,如果拷贝到n
个字节还没有碰到'\0'
,那么也结束,调用者负责提供适当的n
值,以确保读写不会越界,比如让n
的值等于dest
所指向的内存空间的大小。这意味着dest
有可能不是以'\0'
结尾的。如果src
字符串全部拷完了不足n
个字节,那么还差多少个字节就补多少个'\0'。
void *memcpy(void *dest, const void *src, size_t n);
说明:memcpy
函数从src
所指的内存地址拷贝n
个字节到dest
所指的内存地址,和strncpy
不同,memcpy
并不是遇到'\0'
就结束,而是一定会拷贝完n
个字节。
void *memmove(void *dest, const void *src, size_t n);
说明:memmove
也是从src
所指的内存地址拷贝n
个字节到dest
所指的内存地址,虽然叫move但其实也是拷贝而非移动。但是和memcpy
有一点不同,memcpy
的两个参数src
和dest
所指的内存区间如果重叠则无法保证正确拷贝,而memmove
却可以正确拷贝。
4、连接字符串
char *strcat(char *dest, const char *src);
说明:调用者必须确保dest
缓冲区足够大,否则会导致缓冲区溢出错误。strncat
函数通过参数n
指定一个长度,就可以避免缓冲区溢出错误。
char *strncat(char *dest, const char *src, size_t n);
返回值:dest指向哪,返回的指针就指向哪
说明:参数n
的含义和strncpy
的参数n
不同,它并不是缓冲区dest
的长度,而是表示最多从src
缓冲区中取n
个字符(不包括结尾的'\0'
)连接到dest
后面。如果src
中前n
个字符没有出现'\0'
,则取前n
个字符再加一个'\0'
连接到dest
后面,所以strncat
总是保证dest
缓冲区以'\0'
结尾。
5、比较字符串
int memcmp(const void *s1, const void *s2, size_t n);
说明:
memcmp
从前到后逐个比较缓冲区s1
和s2
的前n
个字节(不管里面有没有'\0'
),如果s1
和s2
的前n
个字节全都一样就返回0,如果遇到不一样的字节,s1
的字节比s2
小就返回负值,s1
的字节比s2
大就返回正值。
int strcmp(const char *s1, const char *s2);
strcmp
把s1
和s2
当字符串比较,在其中一个字符串中遇到'\0'
时结束,按照上面的比较准则,"ABC"
比"abc"
小,"ABCD"
比"ABC"
大,"123A9"
比"123B2"
小。
int strncmp(const char *s1, const char *s2, size_t n);
strncmp
的比较结束条件是:要么在其中一个字符串中遇到'\0'
结束(类似于strcmp
),要么比较完n
个字符结束(类似于memcmp
)。
6、搜索字符串
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
返回值:如果找到字符c,返回字符串s中指向字符c的指针,如果找不到就返回NULL
说明:strchr
在字符串s
中从前到后查找字符c
,找到字符c
第一次出现的位置时就返回,返回值指向这个位置,如果找不到字符c
就返回NULL
。strrchr
和strchr
类似,但是从右向左找字符c
,找到字符c
第一次出现的位置就返回。
char *strstr(const char *haystack, const char *needle);
返回值:如果找到子串,返回值指向子串的开头,如果找不到就返回NULL
说明:strstr
在一个长字符串中从前到后找一个子串(Substring),找到子串第一次出现的位置就返回,返回值指向子串的开头,如果找不到就返回NULL。
7、分割字符串
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
返回值:返回指向下一个Token的指针,如果没有下一个Token了就返回NULL
说明:delim
是分隔符,可以指定一个或多个分隔符,strtok
遇到其中任何一个分隔符就会分割字符串。第一次调用要把字符串首地址传给strtok
的第一个参数,以后每次调用第一个参数只要传NULL
就可以了,strtok
函数自己会记住上次处理到字符串的什么位置(显然这是通过strtok
函数中的一个静态指针变量记住的)。
strtok_r
函数则不存在这个问题,它的内部没有静态变量,调用者需要自己分配一个指针变量来维护字符串中的当前处理位置,每次调用时把这个指针变量的地址传给strtok_r
的第三个参数,告诉strtok_r
从哪里开始处理,strtok_r
返回时再把新的处理位置写回到这个指针变量中(这是一个Value-result参数)。strtok_r
末尾的r就表示可重入(Reentrant)。
char * strsep(char **s1, const char *delimt);
说明: 被分割字串要被改变,所以不能操作存放在静态存储区的字串常量,分割符要被替换成’\0’,需要传二级指针,因为s1是指向分割字串,第一次指向源字串,调用后指向分割后的下一个token。所以s1会改变,需要传递二级指针。