C语言string.h库知识点详解
什么是库?
在C语言中,字符串实际上是以空字符’\0’结尾的字符数组。
使用这些函数之前,需要在程序开头包含这个头文件:#include <string.h>
重要概念:空字符
C语言使用空字符’\0’(ASCII码为0)来标记字符串的结束位置。所有字符串函数都依赖这个特殊字符来判断字符串的长度。
关于缓冲区安全
许多传统字符串函数(如strcpy, strcat)不会检查目标缓冲区的长度,可能导致缓冲区溢出。C11标准引入了一批更安全的函数(如strcpy_s, strcat_s),建议在安全性要求高的场景中使用。
字符串操作函数详解
1. 字符串长度函数
strlen – 计算字符串长度
作用: 计算字符串的长度(不包括结尾的’\0’)
参数: str – 要计算长度的字符串
返回值: 字符串中字符的个数(不包括空字符)
注意:
如果字符串没有以’\0’结尾,strlen函数会继续向后读取内存,直到遇到’\0’,可能导致读取越界和未定义行为。
2. 字符串复制函数
strcpy – 字符串复制
作用: 将源字符串复制到目标位置(包括结尾的’\0’)
参数:
- dest – 目标数组(必须足够大)
- src – 源字符串
返回值: 目标字符串的指针
安全警告:
strcpy不会检查目标缓冲区大小,如果源字符串比目标缓冲区大,会导致缓冲区溢出(buffer overflow)漏洞。建议使用更安全的strncpy或strcpy_s代替。
strncpy – 安全字符串复制
作用: 从源字符串复制最多n个字符到目标位置
参数:
- dest – 目标数组
- src – 源字符串
- n – 最多复制的字符数
返回值: 目标字符串的指针
特点:
如果源字符串长度小于n,则剩余空间会用’\0’填充。如果源字符串长度大于或等于n,则不会自动添加’\0’。
3. 字符串连接函数
strcat – 字符串连接
作用: 将源字符串追加到目标字符串的末尾(目标字符串必须有足够的空间)
参数:
- dest – 目标数组(必须足够大)
- src – 要追加的字符串
返回值: 目标字符串的指针
安全警告:
strcat不会检查目标缓冲区大小,可能导致缓冲区溢出。建议使用更安全的strncat或strcat_s。
strncat – 安全字符串连接
作用: 从源字符串追加最多n个字符到目标字符串末尾
参数:
- dest – 目标数组
- src – 要追加的字符串
- n – 最多追加的字符数
返回值: 目标字符串的指针
特点:
函数会自动在目标字符串末尾添加’\0’。如果源字符串长度小于n,只会复制到源字符串的结尾(包括’\0’)。
4. 字符串比较函数
strcmp – 字符串比较
作用: 按字典顺序比较两个字符串
返回值:
- 小于0:str1小于str2
- 等于0:str1等于str2
- 大于0:str1大于str2
strncmp – 安全字符串比较
作用: 比较两个字符串的前n个字符
返回值: 和strcmp相同
使用场景:
当你只想比较字符串的前一部分时非常有用,比如比较文件扩展名。
5. 字符串查找函数
strchr – 查找字符
作用: 在字符串中查找指定字符第一次出现的位置
返回值: 指向字符第一次出现位置的指针,如果没找到则返回NULL
strstr – 查找子串
作用: 在字符串haystack中查找子串needle第一次出现的位置
返回值: 指向子串第一次出现位置的指针,如果没找到则返回NULL
6. 内存操作函数
这些函数可以操作任意内存块,但常用于处理字符串:
memset – 内存设置
作用: 将内存块的前n个字节设置为指定值
常用场景: 初始化数组、清零内存
memcpy – 内存复制
作用: 从源位置复制n个字节到目标位置
注意: 处理内存重叠时行为未定义(应使用memmove)
memmove – 安全内存移动
作用: 从源位置复制n个字节到目标位置,能正确处理内存重叠
使用场景: 当源和目标内存区域重叠时
memcmp – 内存比较
作用: 比较两个内存块的前n个字节
返回值: 类似strcmp,返回0表示完全相同
函数分类速查表
字符串基本信息
- strlen – 获取字符串长度
- strchr – 查找字符的位置
- strrchr – 查找字符最后出现的位置
- strstr – 查找子串的位置
字符串操作
- strcpy – 复制字符串
- strncpy – 安全复制字符串
- strcat – 连接字符串
- strncat – 安全连接字符串
- strtok – 分割字符串
字符串比较
- strcmp – 比较两个字符串
- strncmp – 比较字符串的前n个字符
- strcasecmp – 不区分大小写比较(非标准)
- strcoll – 根据本地设置比较字符串
内存操作
- memcpy – 复制内存块
- memmove – 安全复制内存块
- memset – 设置内存块的值
- memcmp – 比较内存块
- memchr – 在内存块中查找字符
核心知识点总结
- 所有字符串都以’\0’结尾
- 记得为目标缓冲区分配足够空间
- 传统函数不检查边界,可能导致溢出
- 优先使用更安全的”n”版本函数
- 字符串函数返回指针便于链式操作
- mem系列函数可用于任意内存块
常见错误
- 忘记分配足够的空间
- 忘记在字符串末尾添加’\0′
- 使用strcpy导致缓冲区溢出
- 使用未初始化的字符串指针
- 使用strtok时未正确处理状态
- 混淆字符和字符串
最佳实践
- 使用strncpy代替strcpy
- 使用strncat代替strcat
- 使用snprintf格式化字符串
- 明确字符串长度再操作
- 使用const保护不应修改的字符串
- 考虑使用更安全的C11函数