C语言字符串函数

C语言字符串函数全面详解

我将系统性地讲解C语言中所有重要的字符串处理函数,包括它们的用法、参数、返回值和注意事项。

1. 字符串基础概念

字符串表示

在C语言中,字符串是以\0(空字符)结尾的字符数组。

char str1[] = "Hello";           // 自动添加\0
char str2[6] = {'H','e','l','l','o','\0'}; // 手动添加\0
char *str3 = "Hello";            // 字符串字面量(常量区)

2. 字符串长度函数

strlen

#include <string.h>
size_t strlen(const char *str);
  • 功能:计算字符串长度(不包括\0
  • 示例
char str[] = "Hello";
printf("长度: %zu\n", strlen(str)); // 输出: 5
  • 注意:如果字符串没有\0,会导致未定义行为

3. 字符串复制函数

strcpy

char *strcpy(char *dest, const char *src);
  • 功能:将src复制到dest(包括\0
  • 危险:不检查目标缓冲区大小
char dest[10];
strcpy(dest, "Hello"); // 安全
// strcpy(dest, "This is too long"); // 危险!缓冲区溢出

strncpy

char *strncpy(char *dest, const char *src, size_t n);
  • 功能:安全复制,最多复制n个字符
  • 重要:可能不自动添加\0
char dest[10];
strncpy(dest, "Hello World", 9);
dest[9] = '\0'; // 必须手动添加结束符

strdup(非标准但常用)

// 需要自己实现或检查编译器支持
char *strdup(const char *str) {
    char *new_str = malloc(strlen(str) + 1);
    if (new_str) strcpy(new_str, str);
    return new_str;
}

4. 字符串连接函数

strcat

char *strcat(char *dest, const char *src);
  • 功能:将src连接到dest末尾
char path[50] = "/home/";
strcat(path, "user"); // path变为"/home/user"

strncat

char *strncat(char *dest, const char *src, size_t n);
  • 功能:安全连接,最多连接n个字符
  • 优点:自动添加\0
char buf[20] = "Hello";
strncat(buf, " World!!!", 6); // 只连接" World"

5. 字符串比较函数

strcmp

int strcmp(const char *str1, const char *str2);
  • 返回值
    • <0:str1 < str2
    • =0:str1 = str2
    • >0:str1 > str2
printf("%d\n", strcmp("apple", "banana")); // 负数
printf("%d\n", strcmp("apple", "apple"));  // 0

strncmp

int strncmp(const char *str1, const char *str2, size_t n);
  • 功能:比较前n个字符
// 比较前3个字符
if (strncmp("apple", "application", 3) == 0) {
    printf("前3字符相同\n");
}

strcasecmp(不区分大小写,非标准)

// 需要包含相应头文件
#include <strings.h> // 或 <string.h>
int strcasecmp(const char *s1, const char *s2);

6. 字符串查找函数

strchr

char *strchr(const char *str, int c);
  • 功能:查找字符c第一次出现的位置
char *p = strchr("hello", 'l'); // 指向第一个'l'

strrchr

char *strrchr(const char *str, int c);
  • 功能:查找字符c最后一次出现的位置
char *p = strrchr("hello", 'l'); // 指向第二个'l'

strstr

char *strstr(const char *haystack, const char *needle);
  • 功能:查找子串
char *p = strstr("hello world", "world"); // 找到"world"

strpbrk

char *strpbrk(const char *str, const char *accept);
  • 功能:查找字符集中任意字符的第一次出现
char *p = strpbrk("hello", "aeiou"); // 找到'e'

7. 字符串分割函数

strtok

char *strtok(char *str, const char *delim);
  • 功能:根据分隔符分割字符串
  • 注意:会修改原字符串,非线程安全
char data[] = "name=john;age=25";
char *token = strtok(data, ";=");
while (token) {
    printf("%s\n", token);
    token = strtok(NULL, ";=");
}

strtok_r(可重入版本)

char *strtok_r(char *str, const char *delim, char **saveptr);

8. 内存操作函数(常用于字符串)

memcpy

void *memcpy(void *dest, const void *src, size_t n);
  • 功能:内存复制(不处理重叠)
char src[] = "hello";
char dest[10];
memcpy(dest, src, 6); // 复制5字符+\0

memmove

void *memmove(void *dest, const void *src, size_t n);
  • 功能:安全内存复制(处理重叠)
char str[] = "abcdef";
memmove(str + 2, str, 3); // 可以处理重叠区域

memset

void *memset(void *ptr, int value, size_t n);
  • 功能:内存设置
char buffer[100];
memset(buffer, 0, 100); // 清零
memset(buffer, 'A', 10); // 前10字节设为'A'

memcmp

int memcmp(const void *ptr1, const void *ptr2, size_t n);
  • 功能:内存比较
if (memcmp("apple", "apply", 3) == 0) {
    printf("前3字节相同\n");
}

9. 字符串转换函数

字符分类函数(ctype.h)

#include <ctype.h>

isalpha(c);  // 是否为字母
isdigit(c);  // 是否为数字
isalnum(c);  // 是否为字母或数字
islower(c);  // 是否为小写
isupper(c);  // 是否为大写
isspace(c);  // 是否为空白字符

大小写转换

tolower('A'); // 返回'a'
toupper('a'); // 返回'A'

10. 数值转换函数

字符串转数值

#include <stdlib.h>

int atoi(const char *str);         // 字符串转整数
double atof(const char *str);      // 字符串转浮点数
long atol(const char *str);        // 字符串转长整数

// 安全版本
long strtol(const char *str, char **endptr, int base);
double strtod(const char *str, char **endptr);

数值转字符串

#include <stdio.h>

char buffer[20];
int num = 255;

// 方法1: sprintf
sprintf(buffer, "%d", num);

// 方法2: 安全版本snprintf
snprintf(buffer, sizeof(buffer), "数值: %d", num);

11. 格式化字符串函数

sprintf / snprintf

int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
char info[100];
sprintf(info, "姓名: %s, 年龄: %d", "John", 25);
snprintf(info, sizeof(info), "格式化..."); // 安全版本

12. 高级字符串处理技巧

安全字符串处理函数

// 安全的字符串复制
char* safe_strcpy(char *dest, const char *src, size_t dest_size) {
    if (dest_size == 0) return dest;
    strncpy(dest, src, dest_size - 1);
    dest[dest_size - 1] = '\0';
    return dest;
}

// 安全的字符串连接
char* safe_strcat(char *dest, const char *src, size_t dest_size) {
    size_t dest_len = strlen(dest);
    if (dest_len >= dest_size) return dest; // 没有空间了
    
    strncat(dest, src, dest_size - dest_len - 1);
    return dest;
}

字符串处理综合示例

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

void comprehensive_string_demo() {
    // 1. 基本操作
    char text[100] = "Hello World";
    printf("原始: %s\n", text);
    printf("长度: %zu\n", strlen(text));
    
    // 2. 查找和替换
    char *found = strstr(text, "World");
    if (found) {
        strncpy(found, "C Language", 10);
    }
    printf("替换后: %s\n", text);
    
    // 3. 分割字符串
    char data[] = "apple,banana,cherry";
    char *token = strtok(data, ",");
    while (token) {
        printf("水果: %s\n", token);
        token = strtok(NULL, ",");
    }
    
    // 4. 数值转换
    char num_str[] = "123.45";
    double num = atof(num_str);
    printf("数值: %.2f\n", num);
    
    // 5. 大小写转换
    char mixed[] = "HeLLo";
    for (int i = 0; mixed[i]; i++) {
        mixed[i] = tolower(mixed[i]);
    }
    printf("小写: %s\n", mixed);
}

int main() {
    comprehensive_string_demo();
    return 0;
}

13. 常见错误和最佳实践

要避免的错误

// 错误1: 缓冲区溢出
char small[5];
strcpy(small, "This is too long"); // 危险!

// 错误2: 使用未初始化的指针
char *ptr;
strcpy(ptr, "hello"); // 未定义行为

// 错误3: 修改字符串字面量
char *p = "constant";
p[0] = 'C'; // 尝试修改只读内存,会崩溃

最佳实践

  1. 总是检查缓冲区大小
  2. 使用安全函数(带n的版本)
  3. 手动添加字符串结束符
  4. 验证函数返回值
  5. 使用const保护不应修改的字符串

这个全面的指南涵盖了C语言中最重要的字符串处理函数。掌握这些函数对于编写健壮、安全的C程序至关重要。

posted @ 2025-12-04 11:45  FxorG  阅读(159)  评论(0)    收藏  举报