C语言字符函数与字符串函数详解

C语言字符函数与字符串函数详解

1. 字符分类与转换

<ctype.h> 提供 isalpha、isdigit、isalnum、isspace、islower、isupper 等分类函数,以及 tolower、toupper 转换函数。

1
2
3
4
5
6
7
8
9
10
11
#include <ctype.h>
#include <stdio.h>

int main(void)
{
char text[] = "Hello 2026";
for (size_t i = 0; text[i] != '\0'; ++i)
text[i] = (char)toupper((unsigned char)text[i]);
printf("%s\n", text);
return 0;
}

向 ctype 函数传递普通 char 可能因负值产生未定义行为,稳妥做法是先转换为 unsigned char。

2. strlen

1
2
3
4
5
6
7
size_t my_strlen(const char *str)
{
const char *start = str;
while (*str != '\0')
++str;
return (size_t)(str - start);
}

strlen 不统计结尾的 \0,前提是参数指向合法、以 \0 结尾的字符串。

3. strcpy与strncpy

1
2
3
4
5
6
7
char *my_strcpy(char *dest, const char *src)
{
char *result = dest;
while ((*dest++ = *src++) != '\0')
;
return result;
}

目标空间必须足够大,且源和目标不能重叠。strncpy 在源字符串过长时可能不补 \0,不能简单理解为“绝对安全的strcpy”。

4. strcat与strncat

1
2
char buffer[32] = "Hello";
strcat(buffer, " C");

目标数组必须已经是合法字符串,并具有容纳原内容、追加内容和终止符的空间。strncat 的数量参数表示最多追加多少个源字符,它会在正常情况下补终止符。

5. strcmp与strncmp

1
int result = strcmp("apple", "apply");

返回值只保证小于0、等于0或大于0,不保证一定是 -1 或 1。字符串内容比较必须使用比较函数,不能使用 ==。

6. strstr

strstr 查找子串第一次出现的位置:

1
2
3
const char *position = strstr("hello world", "world");
if (position != NULL)
printf("索引:%td\n", position - "hello world");

简单模拟:

1
2
3
4
5
6
7
8
9
10
11
12
const char *my_strstr(const char *text, const char *pattern)
{
if (*pattern == '\0') return text;
for (; *text != '\0'; ++text)
{
const char *a = text;
const char *b = pattern;
while (*a && *b && *a == *b) { ++a; ++b; }
if (*b == '\0') return text;
}
return NULL;
}

7. strtok

1
2
3
char text[] = "user=lic&lang=c&level=1";
for (char *token = strtok(text, "=&"); token; token = strtok(NULL, "=&"))
printf("%s\n", token);

strtok 会修改原字符串,并在内部保存状态,通常不是线程安全接口。需要保留原字符串时,应先复制。

8. strerror

1
2
3
4
5
6
#include <errno.h>
#include <string.h>

FILE *fp = fopen("missing.txt", "r");
if (fp == NULL)
fprintf(stderr, "%s\n", strerror(errno));

实际工程也可使用 perror 直接输出错误上下文。

9. 总结

字符串函数的共同前提是地址有效、容量足够、终止符正确。使用前不仅要看函数名,还要确认是否修改输入、是否允许重叠、如何处理长度和 \0。