Linux系统编程-C语言常用字符串处理函数
strlen - 计算字符串长度
功能:计算一个字符串的长度,即从起始地址开始到第一个空字符('\0'
)前的字符个数(不包括'\0'
本身)。
原型:
1 | size_t strlen(const char *str); |
参数:
str
:要计算长度的字符串的指针。
返回值:
- 返回字符串的长度,类型为
size_t
(通常是无符号整数)。
重要特点:
- 它只是遍历内存,直到遇到
'\0'
为止。如果传入的指针不是指向一个以'\0'
结尾的字符串,函数会继续访问后面的内存,导致未定义行为(如崩溃)。
示例:
1 |
|
strcpy - 字符串复制
功能:将一个字符串(包括结束符 '\0'
)复制到另一个字符数组中。
原型:
1 | char *strcpy(char *dest, const char *src); |
参数:
dest
:目标字符数组的指针,用于存放复制后的字符串。src
:源字符串的指针。
返回值:
- 返回目标字符串的指针
dest
。
重要警告:
strcpy
不会检查目标数组dest
的大小是否足够容纳src
的内容。 如果src
的长度大于dest
分配的空间,会导致缓冲区溢出,这是非常严重的安全漏洞。务必确保dest
的空间足够大。
安全替代品:strncpy
或非标准但更安全的 strlcpy
(在某些系统中可用)。
示例:
1 |
|
strncpy - 受限的字符串复制
功能:将源字符串的前 n
个字符复制到目标数组。如果源字符串的长度小于 n
,则会用空字符('\0'
)填充剩余空间。
原型:
1 | char *strncpy(char *dest, const char *src, size_t n); |
参数:
dest
:目标数组。src
:源字符串。n
:最多复制的字符数。
返回值:
- 返回目标字符串的指针
dest
。
重要特点与陷阱:
- 它可能不会在目标字符串的末尾自动添加
'\0'
。如果源字符串的前n
个字符中没有'\0'
,那么dest
中的结果就不会以'\0'
结尾。这是一个常见的错误来源。 - 通常需要手动确保字符串以
'\0'
结尾,例如:dest[n-1] = '\0';
。
示例:
1 |
|
strcat - 字符串连接
功能:将源字符串 src
的一个副本追加到目标字符串 dest
的末尾(覆盖 dest
原有的终止空字符 '\0'
),并在新字符串的末尾添加一个新的 '\0'
。
原型:
1 | char *strcat(char *dest, const char *src); |
参数:
dest
:目标数组,必须包含一个有效的 C 字符串,并且有足够的空间容纳连接后的结果。src
:要追加的源字符串。
返回值:
- 返回目标字符串的指针
dest
。
重要警告:
- 和
strcpy
一样,它不检查目标数组的剩余空间是否足够。必须由程序员保证dest
有足够的空间容纳src
和原来的dest
以及一个额外的'\0'
。否则会导致缓冲区溢出。
安全替代品:strncat
示例:
1 |
|
strncat - 受限的字符串连接
功能:将源字符串的前 n
个字符追加到目标字符串的末尾,并总是添加一个终止空字符 '\0'
。
原型:
1 | char *strncat(char *dest, const char *src, size_t n); |
参数:
dest
:目标数组。src
:源字符串。n
:最多追加的字符数。
返回值:
- 返回目标字符串的指针
dest
。
重要特点:
- 比
strcat
更安全,因为它限制了追加的字符数。 - 它总是会在结果字符串的末尾添加一个
'\0'
,所以最终字符串dest
的长度最多增加n
个字符(n+1
个字节,包括'\0'
)。这是它与strncpy
的一个重要区别,也更不容易出错。
示例:
1 |
|
strcmp - 字符串比较
功能:按字典顺序(ASCII 码顺序)比较两个字符串。
原型:
1 | int strcmp(const char *str1, const char *str2); |
参数:
str1
,str2
:要比较的两个字符串。
返回值:
- 如果
str1
小于str2
,则返回一个负整数。 - 如果
str1
等于str2
,则返回 0。 - 如果
str1
大于str2
,则返回一个正整数。
比较规则:
逐个字符比较它们的 ASCII 值,直到遇到不同的字符或遇到 '\0'
为止。
示例:
1 |
|
strncmp - 受限的字符串比较
功能:比较两个字符串的前 n
个字符。
原型:
1 | int strncmp(const char *str1, const char *str2, size_t n); |
参数:
str1
,str2
:要比较的字符串。n
:要比较的最大字符数。
返回值:
- 与
strcmp
类似,返回负整数、0 或正整数。
示例:
1 |
|
strchr - 查找字符第一次出现的位置
功能:在字符串 str
中查找第一次出现字符 c
(转换为 char
)的位置。
原型:
1 | char *strchr(const char *str, int c); |
参数:
str
:要被搜索的字符串。c
:要查找的字符(以int
形式传递,但内部会转换为char
)。
返回值:
- 如果找到,返回指向该字符的指针。
- 如果未找到,返回
NULL
。
示例:
1 |
|
strstr - 查找子字符串第一次出现的位置
功能:在字符串 haystack
中查找第一次出现子字符串 needle
的位置。
原型:
1 | char *strstr(const char *haystack, const char *needle); |
参数:
haystack
:要被搜索的主字符串。needle
:要查找的子字符串。
返回值:
- 如果找到,返回指向子字符串起始位置的指针。
- 如果未找到,返回
NULL
。
示例:
1 |
|
总结与安全提示
函数 | 功能 | 主要风险 |
---|---|---|
strlen |
求长度 | 如果字符串无 '\0' ,则导致未定义行为 |
strcpy |
复制 | 缓冲区溢出 |
strncpy |
受限复制 | 可能不以 '\0' 结尾 |
strcat |
连接 | 缓冲区溢出 |
strncat |
受限连接 | 相对安全,但仍需注意总长度 |
strcmp |
比较 | 无 |
strncmp |
受限比较 | 无 |
strchr |
查找字符 | 无 |
strstr |
查找子串 | 无 |
最佳实践:
- 始终检查目标缓冲区的大小:在使用
strcpy
,strcat
等函数之前,确保目标数组足够大。使用sizeof(dest)
来获取数组的实际大小。 - 优先使用“n”系列函数:如使用
strncpy
,strncat
代替它们的旧版本,并正确处理终止符(特别是对于strncpy
)。 - 考虑使用更安全的替代函数:在一些平台或编译环境下,可以考虑使用非标准但更安全的函数,如
strlcpy
和strlcat
。 - 始终检查以空字符结尾:确保操作的字符串都是有效的、以
'\0'
结尾的 C 字符串。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Cokode' Blog!