C语言-字符串操作函数手册:语法、技巧与经典应用
目录
* gets()/fgets() - 字符串输入
* puts() - 字符串输出
* strlen() - 字符串长度获取
* strcpy()/strncpy() - 字符串复制
* strcat()/strncat() - 字符串连接
* strcmp()/strncmp() - 字符串比较
* strchr()/strrchr() - 查找字符
* memset() - 内存设置
* memcpy() - 内存复制
* sprintf()/snprintf() - 格式化字符串写入
C语言中的字符串处理是编程基础中的核心内容。由于C语言没有内置字符串类型,而是使用字符数组和指针来处理字符串,因此标准库提供了一系列字符串操作函数。本文将全面介绍这些函数的正确使用方法、实际案例以及常见错误。
* gets()/fgets() - 字符串输入
char *gets(char *str); // 已废弃
fgets(str, sizeof(str), stdin); // 安全版本
功能:从标准输入读取一行到str指向的缓冲区
问题:极易发生缓冲区溢出
C11标准已移除该函数 替代方案:fgets
示例:
char name[20];
printf("请输入您的姓名:");
fgets(name, sizeof(name), stdin); // 安全读取输入
printf("您好,%s", name);
* puts() - 字符串输出
int puts(const char *str);
功能:输出字符串并自动添加换行符
示例:puts("Hello World"); // 输出:Hello World\n
特点:比printf()效率更高,自动添加换行符
* strlen() - 字符串长度获取
size_t strlen(const char *str);
功能:计算字符串长度(不含'\0')
示例:
char str[] = "Hello";
printf("%zu", strlen(str)); // 输出5
注意:遇到'\0'停止,不计算终止符
* strcpy()/strncpy() - 字符串复制
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
功能:复制src到dest
对比:
函数 | 安全性 | 是否自动补'\0' | 推荐指数 |
---|---|---|---|
strcpy | 不安全 | 是 | ★★☆☆☆ |
strncpy | 较安全 | 否 | ★★★☆☆ |
安全示例:
char dest[10];
strncpy(dest, src, sizeof(dest)-1);
dest[sizeof(dest)-1] = '\0';
* strcat()/strncat() - 字符串连接
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
功能:将src追加到dest末尾
安全示例:
char dest[20] = "Hello";
strncat(dest, " World!", sizeof(dest)-strlen(dest)-1);
常见错误:目标缓冲区空间不足,忘记初始化目标字符串
* strcmp()/strncmp() - 字符串比较
int strcmp(const char *str1, const char *str2);
int strncmp(const char *str1, const char *str2, size_t n);
返回值:<0: str1 < str2
=0: str1 == str2
>0: str1 > str2
示例:
if(strncmp(str1, str2, 5) == 0) {
// 前5个字符相同
}
* strchr()/strrchr() - 查找字符
char *strchr(const char *str, int c); // 正向查找
char *strrchr(const char *str, int c); // 反向查找
示例:
char *p = strchr("Hello", 'l'); // 指向第一个'l'
char *p = strrchr("Hello", 'l'); // 指向第二个'l'
* memset() - 内存设置
void *memset(void *str, int c, size_t n);
用途:将 str
指向的内存区域的前 n
个字节设置为特定值 c,
常用于初始化字符串/内存块
示例:
char buffer[10];
// 初始化为0
memset(buffer, 0, sizeof(buffer));
printf("Buffer: %s\n", buffer); // 输出空字符串
// 初始化为'A'
memset(buffer, 'A', 5);
buffer[5] = '\0'; // 添加终止符
printf("Buffer: %s\n", buffer); // 输出:AAAAA
注意事项:不会自动添加字符串终止符 \0
* memcpy() - 内存复制
void *memcpy(void *dest, const void *src, size_t n);
功能:从 src
指向的内存地址复制 n
个字节到 dest
指向的内存地址
适用于任何数据类型的内存复制
常用于字符串复制(比strcpy更快)
示例:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello World";
char dest[20];
// 复制字符串
memcpy(dest, src, strlen(src)+1); // +1包含终止符
printf("Copied: %s\n", dest); // 输出:Hello World
// 复制整型数组
int nums1[5] = {1,2,3,4,5};
int nums2[5];
memcpy(nums2, nums1, sizeof(nums1));
return 0;
}
* sprintf()/snprintf() - 格式化字符串写入
int sprintf(char *str, const char *format, ...); // 不安全版本
int snprintf(char *str, size_t size, const char *format, ...); // 安全版本
功能:将格式化数据写入字符串缓冲区,snprintf()
会限制写入长度防止溢出
参数 | sprintf | snprintf | 说明 |
---|---|---|---|
str | ✔️ | ✔️ | 目标缓冲区 |
size | ❌ | ✔️ | 缓冲区最大容量(含\0 ) |
format | ✔️ | ✔️ | 格式化字符串 |
... | ✔️ | ✔️ | 可变参数 |
返回值 | int | int | sprintf: 成功返回写入字符数(不含\0 ),失败返回负数snprintf: 成功返回欲写入的字符数(不含\0 ),若超过size则返回需要的大小,失败返回负数 |
示例:
char buffer[50] = {0};
int year = 2025;
sprintf(buffer, "当前年份:%d,欢迎使用C语言!", year);
printf("%s\n", buffer); // 输出:当前年份:2025,欢迎使用C语言!
#include <stdio.h>
#include <string.h>
int main() {
char buffer[50] = {0}; // 初始化缓冲区为全零
int year = 2025;
/* 安全替换方案:snprintf
* 参数说明:
* 1. buffer - 目标缓冲区
* 2. sizeof(buffer) - 最大写入长度(自动计算数组大小)
* 3. 格式化字符串和参数
*/
int result = snprintf(buffer, sizeof(buffer),
"当前年份:%d,欢迎使用C语言!", year);
/* 检查返回值:
* 1. 若返回值 >= sizeof(buffer),说明内容被截断
* 2. 若返回值 < 0,说明发生错误
*/
if (result >= sizeof(buffer)) {
printf("警告:输出被截断!需要 %d 字节,但缓冲区只有 %zu 字节\n",
result, sizeof(buffer));
} else if (result < 0) {
perror("snprintf 出错");
return 1;
}
printf("%s\n", buffer); // 输出:当前年份:2025,欢迎使用C语言!
return 0;
}
参考:C语言处理字符串的十个函数(附带大量实例)_c语言字符串的函数-CSDN博客
常用的字符串处理函数_常用字符串处理函数-CSDN博客