c语言字符串操作
比较字符串
strcmp()
函数原型:**int (const char _Str1,const char _Str2);
函数要比较的是字符串的内容,不是字符串的地址。
如果在机器排序序列(通常是ASCII值)中第1个字符串位于第2个字符串前面,strcmp()中就返回负数,表面第一个字符小于第2个字符,反之,strcmp()则返回正数。如果两个字符串开始的几个字符都相同,strcmp()会依次比较每个字符,直到发现第1对不同的字符为止。然后,返回相应的值。
|

strncmp()
函数原型:**int strncmp(const char _Str1,const char _Str2,size_t _MaxCount);
比较字符串str1 和str2 中至多count 个字符,如果参数中任一字符串长度小于count, 那么当比较到第一个空值结束符时,就结束处理。
|

拼接字符串
strcat()
函数原型为:char * strcat(char * Dest,const char * Source);
strcat()函数接受两个字符串作为参数。该函数把第2个字符串的备份附加在第1个字符串末尾,返回值为第1个参数,即拼接第2个字符串后的第1个字符串的地址。
strcat()函数无法检查第1个数组是否能容纳第2个字符串。如果分配给第1个数组的空间不够大,多出来的字符溢出到相邻存储单元时就会出问题。
(代码中的m_fgets()函数是对fgets()的处理,这里可以当作是gets()的替换,了解详情看c语言输出输出一文)
|
输入输出结果

strncat()
函数原型:*char strncat(char * Dest,const char * Source,size_t _Count)
用strncat()函数的第3个参数指定了最大添加字符数。例如,strncat(d,s,5)将把s 字符串的内容附加给d,在加到第5个字符或遇到空字符'\0'
时停止。因此,算上空字符d数组应该足够大,以容纳原始字符串(不包含空字符)、添加原始字符串在后面的5字符和末尾的空字符。
建议n的取值为目标数组大小-字符串长度-1
(代码中的m_fgets()函数是对fgets()的处理,这里可以当作是gets()的替换,了解详情看c语言输出输出一文)
|
输入输出结果

拷贝字符串
strcpy()
函数原型:*char * strcpy(char Dest,const char * Source);
strcpy()函数相当于字符串赋值运算符,strcpy()第2个参数指向的字符串被拷贝至第1个参数指向的数组中。第1个参数不必指向数组的开始,可用于拷贝数组的部分。strcpy()把源字符串中的空字符’\0’也拷贝在内

|
strncpy
函数原型:**char strncpy(char target,const char * Source,size_t _Count)
strcpy()和strcat()都有同样的问题,它们都不能检查目标空间是否能容纳源字符串的副本。strncpy()更安全,该函数的第3个参数指明可拷贝的最大字符数。
如果source中的字符数小于n,则拷贝整个字符串,包括空字符。但是,strncpy()拷贝字符串的长度不会超过n
|

如果拷贝到第n个字符时还未拷贝完整个源字符串,就不会拷贝空字符。所以,拷贝的副本中不一定有空字符。

拷贝的目标数组中没有空字符结尾,D就不是一个字符串,例如下代码
|

鉴于此,把n设置为比目标数组大小少1
,然后把数组最后一个元素设置为空字符\0,确保储存的是一个字符串。
|

- 如果目标空间D能容纳源字符串的副本,那么从源字符串S拷贝的空字符便是该副本的结尾:
- 如果目标空间D装不下副本,则把副本S最后一个元素设置为空字符。
切割字符串
strtok()
函数原型:char *strtok(char *str, const char *delim);
str
:要分割的字符串。如果是第一次调用,需要传入待分割的字符串;后续调用应传入NULL
。delim
:一个包含所有分隔符的字符串。strtok
会在原字符串中插入\0
字符,以终止每个标记,因此原字符串会被修改。返回值为指向下一个标记的指针。如果没有更多的标记可供提取,则返回
NULL
。(标记是由一系列字符组成的子字符串,这些字符被分隔符分开。例如,在字符串
"Hello, world!"
中,逗号和空格是分隔符,标记包括"Hello"
和"world"
)
|
输出结果

strtok 不是线程安全的。如果需要在多线程环境中使用,可以考虑使用 strtok_r
strtok_r()
函数原型:**char *strtok_r(char str, const char delim, char **saveptr);strtok_r
需要额外的参数来维护上下文,这使得它在多线程环境中更安全
- str:要分割的字符串。如果是第一次调用此函数,这个参数传入待分割的字符串;后续调用时传入
NULL
。 - delim:分隔符字符串,包含所有可能用作分隔的字符。
- saveptr:指向
char*
指针的指针,用于保存上下文信息,以便后续调用继续从上次停止的位置开始。
|

sscanf()
函数原型:**int sscanf(const char str, const char format, …);
返回值:成功读取的项目数。如果没有读取任何项,则返回 0;如果发生错误,则返回 EOF。
作用:从字符串中读取格式化的数据
|

sprintf()
函数原型:**int sprintf(char str, const char format, …);
返回值为写入到字符串的字符总数,不包括终止的空字符。
sprintf()函数格式化字符串并写入到str中。
|

常见的字符串操作
char * strchr(const char * s,int c); 字符查找
如果s字符串中包含c字符,该函数返回指向s字符串第一次出现的位置的指针(末尾的空字符也是字符串的一部分,所以在查找范围内);如果在字符串s中未找到c字符,该函数则返回空指针。
char* strrchr(const char* s,int c);字符查找
该函数返回s字符串中c字符的最后一次出现的位置(末尾的空字符也是字符串的一部分,所以在查找范围内)。如果未找到c字符,则返回空指针。char * strpbrk(const char *s1,const char *s2);字符查找
如果s1字符中包含s2字符串中的任意字符,该函数返回指向s1字符串首位置的指针:如果在s1字符串中未找到任何s2字符串中的字符,则返回空字符。char *strstr(const char*s1,const char*s2);子字符串查找
该函数返回指向s1字符串中s2字符串出现的首位置。如果在s1中没有找到s2,则返回空指针int atoi(const char *str);将字符串转换为int整数
如果字符串仅以整数开头,atio()函数也能处理,它只把开头的整数转换为字符。例如atoi(“42regular”)将返回整数 42。**如果字符串无法转换(例如,前导字符不是数字),则返回 0。然而C标准规定,这种情况下的行为是未定义的。**因此,使用有错误检测功能的strtol()函数会更安全。
long strtol(const char *str, char **endptr, int base);将字符串转换为int整数
endptr指向字符指针的指针,用于存储指向解析后字符串中未转换部分的指针;base表示进制,支持 2 到 36 之间的值
返回转换后的长整型值。如果没有可转换的数字,则返回 0。如果发生溢出,则返回
LONG_MAX
或LONG_MIN
,并设置errno
为ERANGE
,示例代码如下:
int main() {
const char *numStr = "12345well";
char *endptr;
long num = strtol(numStr, &endptr, 10);
if (*endptr != '\0') {
printf("Converted number: %ld\n", num);
printf("Conversion stopped at: %s\n", endptr);
} else {
printf("Converted number: %ld\n", num);
}
printf("------------------------------------------------------\n");
// 处理溢出
const char *largeNumStr = "99999999999999999999"; // 超过 long 的范围
errno = 0; // 重置 errno
long largeNum = strtol(largeNumStr, NULL, 10);
if (errno == ERANGE) {
printf("Overflow occurred!\n");
} else {
printf("Converted large number: %ld\n", largeNum);
}
return 0;
}在 C 语言中,可以使用标准库函数将整数转换成字符串。最常用的方法是使用
sprintf
或snprintf
函数。在一些编译器中,你可能还可以使用itoa
函数(例如在某些 MSVC 编译器中),不过它不是标准 C 函数。
int main() {
int num = 12345;
char str[20];
itoa(num, str, 10); // 将整数转换为字符串, 10
printf("%s\n", str);
return 0;
}
//10
ASCII表
ASCII(美国标准信息交换码)是一种字符编码标准,用于表示文本中的字符。
十进制 | 十六进制 | 字符 | 说明 |
---|---|---|---|
0 | 00 | NUL | 空字符 |
1 | 01 | SOH | 标题开始 |
2 | 02 | STX | 正文开始 |
3 | 03 | ETX | 正文结束 |
4 | 04 | EOT | 传输结束 |
5 | 05 | ENQ | 查询 |
6 | 06 | ACK | 确认 |
7 | 07 | BEL | 响铃 |
8 | 08 | BS | 退格 |
9 | 09 | TAB | 水平制表符 |
10 | 0A | LF | 换行 |
11 | 0B | VT | 垂直制表符 |
12 | 0C | FF | 换页 |
13 | 0D | CR | 回车 |
14 | 0E | SO | 移出 |
15 | 0F | SI | 移入 |
16 | 10 | DLE | 数据链路转义 |
17 | 11 | DC1 | 设备控制1 |
18 | 12 | DC2 | 设备控制2 |
19 | 13 | DC3 | 设备控制3 |
20 | 14 | DC4 | 设备控制4 |
21 | 15 | NAK | 拒绝确认 |
22 | 16 | SYN | 同步 |
23 | 17 | ETB | 传输块结束 |
24 | 18 | CAN | 取消 |
25 | 19 | EM | 结束媒介 |
26 | 1A | SUB | 替代 |
27 | 1B | ESC | 转义 |
28 | 1C | FS | 文件分隔符 |
29 | 1D | GS | 组分隔符 |
30 | 1E | RS | 记录分隔符 |
31 | 1F | US | 单元分隔符 |
32 | 20 | (space) | 空格 |
33 | 21 | ! | 感叹号 |
34 | 22 | “ | 双引号 |
35 | 23 | # | 井号 |
36 | 24 | $ | 美元符号 |
37 | 25 | % | 百分号 |
38 | 26 | & | 和 |
39 | 27 | ‘ | 单引号 |
40 | 28 | ( | 左括号 |
41 | 29 | ) | 右括号 |
42 | 2A | * | 星号 |
43 | 2B | + | 加号 |
44 | 2C | , | 逗号 |
45 | 2D | - | 减号 |
46 | 2E | . | 点 |
47 | 2F | / | 斜杠 |
48 | 30 | 0 | 数字0 |
49 | 31 | 1 | 数字1 |
50 | 32 | 2 | 数字2 |
51 | 33 | 3 | 数字3 |
52 | 34 | 4 | 数字4 |
53 | 35 | 5 | 数字5 |
54 | 36 | 6 | 数字6 |
55 | 37 | 7 | 数字7 |
56 | 38 | 8 | 数字8 |
57 | 39 | 9 | 数字9 |
58 | 3A | : | 冒号 |
59 | 3B | ; | 分号 |
60 | 3C | < | 小于号 |
61 | 3D | = | 等号 |
62 | 3E | > | 大于号 |
63 | 3F | ? | 问号 |
64 | 40 | @ | 井字号 |
65 | 41 | A | 大写字母A |
66 | 42 | B | 大写字母B |
67 | 43 | C | 大写字母C |
68 | 44 | D | 大写字母D |
69 | 45 | E | 大写字母E |
70 | 46 | F | 大写字母F |
71 | 47 | G | 大写字母G |
72 | 48 | H | 大写字母H |
73 | 49 | I | 大写字母I |
74 | 4A | J | 大写字母J |
75 | 4B | K | 大写字母K |
76 | 4C | L | 大写字母L |
77 | 4D | M | 大写字母M |
78 | 4E | N | 大写字母N |
79 | 4F | O | 大写字母O |
80 | 50 | P | 大写字母P |
81 | 51 | Q | 大写字母Q |
82 | 52 | R | 大写字母R |
83 | 53 | S | 大写字母S |
84 | 54 | T | 大写字母T |
85 | 55 | U | 大写字母U |
86 | 56 | V | 大写字母V |
87 | 57 | W | 大写字母W |
88 | 58 | X | 大写字母X |
89 | 59 | Y | 大写字母Y |
90 | 5A | Z | 大写字母Z |
91 | 5B | [ | 左中括号 |
92 | 5C | \ | 反斜杠 |
93 | 5D | ] | 右中括号 |
94 | 5E | ^ | 逻辑异或 |
95 | 5F | _ | 下划线 |
96 | 60 | ` | 反引号 |
97 | 61 | a | 小写字母a |
98 | 62 | b | 小写字母b |
99 | 63 | c | 小写字母c |
100 | 64 | d | 小写字母d |
101 | 65 | e | 小写字母e |
102 | 66 | f | 小写字母f |
103 | 67 | g | 小写字母g |
104 | 68 | h | 小写字母h |
105 | 69 | i | 小写字母i |
106 | 6A | j | 小写字母j |
107 | 6B | k | 小写字母k |
108 | 6C | l | 小写字母l |
109 | 6D | m | 小写字母m |
110 | 6E | n | 小写字母n |
111 | 6F | o | 小写字母o |
112 | 70 | p | 小写字母p |
113 | 71 | q | 小写字母q |
114 | 72 | r | 小写字母r |
115 | 73 | s | 小写字母s |
116 | 74 | t | 小写字母t |
117 | 75 | u | 小写字母u |
118 | 76 | v | 小写字母v |
119 | 77 | w | 小写字母w |
120 | 78 | x | 小写字母x |
121 | 79 | y | 小写字母y |
122 | 7A | z | 小写字母z |
123 | 7B | { | 左花括号 |
124 | 7C | | | 竖线 |
125 | 7D | } | 右花括号 |
126 | 7E | ~ | 波浪号 |
127 | 7F | DEL | 删除字符 |
大部分控制字符(如 NUL、BEL 等)用于特殊目的,常用字符包括字母、数字和标点符号。