这个系列主要是我学习《C和指针》这本书的一些笔记,主要关于一些小的细节,目的是供自己学习和参考,详细地部分建议大家可以阅读一下《C和指针》这本书
字符串长度
库函数 strlen
的原型如下:
1 | size_t strlen( char const *string ); |
注意 strlen
返回一个类似为 size_t
的值。这个类型是在头文件 stddef.h
中定义的,它是一个无符号整数类型。在表达式中使用无符号数可能导致不可预料的结果。例如,下面两个表达式看上去是相等的:
1 | if( strlen( x ) >= strlen( y ) ) ... |
但事实上它们是不相等的。第 1 条语句将按照你预想的那样工作,但第 2 条语句的结果将永远是真。strlen
的结果是个无符号数,所以操作符 >=
左边的表达式也将是无符号数,而无符号数绝不可能是负的。
一个栗子
1 |
|
不受限制的字符串函数
最常用的字符串都是 “不受限制” 的,也就是说它们只是通过寻找字符串参数结尾的 NUL
字节来判断它的长度,这些函数一般都指定一块内存用于存放结果字符串。在使用这些函数时,程序员必须保证结果字符串不会溢出这块内存。
复制字符串
用于复制字符串的函数是 strcpy
,它的原型如下所示:
1 | char *strcpy( char *dst, char const *src ); |
这个函数把参数 src
字符串复制到 dst
参数,返回结果为一个指向目标字符数组的指针。如果参数 src
和 dst
在内存中出现重叠,其结果是未定义的。由于 dst
参数将进行修改,因此它必须是个字符数组或者是一个指向动态分配内存的数组的指针,不能使用字符串常量。
需要注意目标字符数组的空间足以容纳需要复制的字符串。否则将会覆盖数组后面的内存空间的值。
一个栗子
1 |
|
连接字符串
要想把一个字符串添加(连接)到另一个字符串的后面,可以使用 strcat
函数。它的原型如下:
1 | char *strcat( char *dst, char const *src ); |
strcat
函数要求 dst
参数原先已经包含了一个字符串(可以是空字符串)。它找到这个字符串的末尾,并把 src
字符串的一份副本添加到这个位置,返回结果为指向目标字符数组的指针。如果 src
和 dst
的位置发生重叠,其结果是未定义的。
一个栗子
1 |
|
字符串比较
库函数 strcmp
用于比较两个字符串,它的原型如下:
1 | int strcmp( char const *s1, char const *s2 ); |
如果 s1
小于 s2
,strcmp
函数返回一个小于零的值;如果 s1
大于 s2
,函数返回一个大于零的值;如果两个字符串相等,函数就返回零。
注意这里是词典比较,且相等是输出 0 而不是 1
一个栗子
1 |
|
长度受限的字符串函数
标准库还包含了一些函数,它们以一种不同的方式处理字符串。这些函数接受一个显式的长度参数,用于限定进行复制或比较的字符数。这些函数提供了一种方便的机制,可以防止难以预料的长字符串从它们的目标数组溢出。
这些函数的原型如下:
1 | char *strncpy( char *dst, char const *src, size_t len ); |
和 strcpy
一样,strncpy
把源字符串的字符复制到目标数组。然而,它总是正好向 dst
写入 len
个字符。如果 strlen( stc )
的值小于 len
,dst
数组就用额外的 NUL
字节填充到 len
长度;如果 strlen( src )
的值大于或等于 len
,那么只有 len
个字符被复制到 dst
中。注意!它的结果将不会以 NUL 字节结尾。
字符串查找函数
查找一个字符
在一个字符串中查找一个特定字符最容易的方法是使用 strchr
和 strrchr
函数,它们的原型如下所示:
1 | char *strchr( char const *str, int ch ); |
注意,它们的第 2 个参数是一个整型值。但是,它包含了一个字符值。strchr
在字符串 str
中查找字符 ch
第 1 次出现的位置,找到后函数返回一个指向该位置的指针。如果该字符并不存在于字符串中,函数就返回一个 NULL
指针。 strrchr
的功能和 strchr
基本一致,只是它所返回的是一个指向字符串该字符最后一次出现的位置(最右边那个)。
一个栗子
1 |
|
查找任何几个字符
strpbrk
是个更为常见的函数。它并不是查找某个特定的字符,而是查找任何一组字符第一次在字符串中出现的位置。它的原型如下:
1 | char *strpbrk( char const *str, char const *group ); |
这个函数返回一个指向 str
中第 1 个匹配 group
中任何一个字符的字符位置。如果未找到匹配,函数返回一个 NULL
指针。
一个栗子
1 |
|
查找一个子串
为了在字符串中查找一个子串,可以使用 strstr
函数,它的原型如下:
1 | char *strstr( char const *s1, char const *s2 ); |
这个函数在 s1
中查找整个 s2
第一次出现的起始位置,并返回一个指向该位置的指针。如果 s2
并没有完整地出现在 s1
的任何地方,函数将返回一个 NULL
指针。如果第 2 个参数是一个空字符串,函数就返回 s1
。
查找一个字符串前缀
strspn
和 strcspn
函数用于在字符串的起始位置对字符计数。它们的原型如下所示:
1 | size_t strspn( char const *str, char const *group ); |
group
字符串指定一个或多个字符。strspn
返回 str
起始部分匹配 group
中任意字符的字符数。
一个栗子
1 |
|
查找标记
strtok
函数从字符串中隔离各个单独的称为标记( token )的部分,并丢弃分隔符。它的原型如下:
1 | char *strtok( char *str, char const *sep ); |
sep
参数是个字符串,定义了用作分隔符的字符集合。第 1 参数指定一个字符串,它包含零个或多个由 sep
字符串中一个或多个分隔符分隔的标记。strtok
找到 str
的下一个标记,并将其用 NUL
结尾,然后返回一个指向这个标记的指针。
一个栗子
1 |
|