# 字符串处理
#include <string.h>
// strlen()函数返回字符串的字节长度,不包括末尾的空字符\0。
size_t strlen(const char* s);
// 字符串的复制,不能使用赋值运算符,直接将一个字符串赋值给字符数组变量。
strcpy(char dest[], const char source[]);
// strncpy()跟strcpy()的用法完全一样,只是多了第3个参数,用来指定复制的最大字符数,防止溢出目标字符串变量的边界。
char* strncpy( char* dest, char* src, size_t n);
strncpy(str1, str2, sizeof(str1) - 1);
// strncpy()不会自己添加\0,如果复制的字符串片段不包含结尾标志,就需要手动添加。
str1[sizeof(str1) - 1] = '\0';
// 连接字符串
// 返回值是一个字符串指针,指向第一个参数。
char* strcat(char* s1, const char* s2);
// strncat()用于连接两个字符串,用法与strcat()完全一致,只是增加了第三个参数,指定最大添加的字符数。在添加过程中,一旦达到指定的字符数,或者在源字符串中遇到空字符\0,就不再添加了。
char* strncat(
char* dest,
const char* src,
size_t n
);
// strncat()总是会在拼接结果的结尾,自动添加空字符\0,
// 所以第三个参数的最大值,应该是str1的变量长度减去str1的字符串长度,再减去1。
// strncat 写入 n+1 个字符
strncat(
str1,
str2,
sizeof(str1) - strlen(str1) - 1
);
// strcmp()函数用于比较两个字符串的内容。
int strcmp(const char* s1, const char* s2);
// 如果两个字符串相同,返回值为0;如果s1小于s2,strcmp()返回值小于0;如果s1大于s2,返回值大于0。
// 只比较到指定的位置。
int strncmp(
const char* s1,
const char* s2,
size_t n
);
// sprintf()函数跟printf()类似,但是用于将数据写入字符串,而不是输出到显示器。
int sprintf(char* s, const char* format, ...);
char first[6] = "hello";
char last[6] = "world";
char s[40];
sprintf(s, "%s %s", first, last);
printf("%s\n", s); // hello world
// snprintf()只比sprintf()多了一个参数n,用来控制写入变量的字符串不超过n - 1个字符,剩下一个位置写入空字符\0。下面是它的原型。
// snprintf()总是会自动写入字符串结尾的空字符。如果你尝试写入的字符数超过指定的最大字符数,snprintf()会写入 n - 1 个字符,留出最后一个位置写入空字符。
// snprintf() 写入 n-1 个字符,最后一个写入 \0。
int snprintf(char*s, size_t n, const char* format, ...);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# strchr(),strrchr()
strchr()和strrchr()都用于在字符串中查找指定字符。 不同之处是,strchr()从字符串开头开始查找,strrchr()从字符串结尾开始查找, 函数名里面多出来的那个r表示 reverse(反向)。
char* strchr(char* str, int c);
char* strrchr(char *str, int c);
char *str = "Hello, world!";
char *p;
p = strchr(str, ','); // p 指向逗号的位置
p = strrchr(str, 'o'); // p 指向 world 里面 o 的位置
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# strspn(),strcspn()
strspn()用来查找属于指定字符集的字符串长度,strcspn()正好相反,用来查找不属于指定字符集的字符串长度。
size_t strspn(char* str, const char* accept);
size_t strcspn(char *str, const char *reject);
char str[] = "hello world";
int n;
n = strspn(str1, "aeiou");
printf("%d\n", n); // n == 0
n = strcspn(str1, "aeiou");
printf("%d\n", n); // n == 1
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
上面示例中,第一个n等于0,因为0号位置的字符h就不属于指定字符集aeiou, 可以理解为开头有0个字符属于指定字符集。第二个n等于1, 因为1号位置的字符e属于指定字符集aeiou,可以理解为开头有1个字符不属于指定字符集。
# strpbrk()
strpbrk()在字符串中搜索指定字符集的任一个字符。
// 它接受两个参数,第一个参数是源字符串,第二个参数是由指定字符组成的字符串。
// 它返回一个指向第一个匹配字符的指针,如果未找到匹配字符,则返回 NULL。
char* strpbrk(const char* s1, const char* s2);
char* s1 = "Hello, world!";
char* s2 = "dow!";
char* p = strpbrk(s1, s2);
printf("%s\n", p); // "o, world!"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# strstr()
char *strstr(
const char* str,
const char* substr
);
// 如果匹配成功,就返回一个指针,指向源字符串里面的子字符串。
// 如果匹配失败,就返回 NULL,表示无法找到子字符串。
char* str = "The quick brown fox jumped over the lazy dogs.";
char* p = strstr(str, "lazy");
printf("%s\n", p == NULL ? "null": p); // "lazy dogs."
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# strtok()
strtok()用来将一个字符串按照指定的分隔符(delimiter),分解成一系列词元(tokens)。
// 它接受两个参数,第一个参数是待拆分的字符串,第二个参数是指定的分隔符。
// 它返回一个指针,指向分解出来的第一个词元,
// 并将词元结束之处的分隔符替换成字符串结尾标志\0。如果没有待分解的词元,它返回 NULL。
char* strtok(char* str, const char* delim);
#include <stdio.h>
#include <string.h>
int main(void) {
char string[] = "This is a sentence with 7 tokens";
char* tokenPtr = strtok(string, " ");
while (tokenPtr != NULL) {
printf("%s\n", tokenPtr);
tokenPtr = strtok(NULL, " ");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# strerror()
strerror()函数返回特定错误的说明字符串。
char *strerror(int errornum);
//它的参数是错误的编号,由errno.h定义。返回值是一个指向说明字符串的指针。
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(void) {
FILE* fp = fopen("NONEXISTENT_FILE.TXT", "r");
if (fp == NULL) {
char* errmsg = strerror(errno);
printf("Error %d opening file: %s\n", errno, errmsg);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# memcpy()
memcpy()用于将一块内存拷贝到另一块内存。该函数的原型定义在头文件string.h。
void* memcpy(
void* restrict dest,
void* restrict source,
size_t n
);
#include <stdio.h>
#include <string.h>
int main(void) {
char s[] = "Goats!";
char t[100];
memcpy(t, s, sizeof(s)); // 拷贝7个字节,包括终止符
printf("%s\n", t); // "Goats!"
char* s = "hello world";
size_t len = strlen(s) + 1;
char *c = malloc(len);
if (c) {
// strcpy() 的写法
strcpy(c, s);
// memcpy() 的写法
memcpy(c, s, len);
}
return 0;
}
// memcpy()可以取代strcpy()进行字符串拷贝,
// 而且是更好的方法,不仅更安全,速度也更快,它不检查字符串尾部的\0字符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# memmove()
memmove()函数用于将一段内存数据复制到另一段内存。它跟memcpy()的主要区别是, 它允许目标区域与源区域有重叠。 如果发生重叠,源区域的内容会被更改;如果没有重叠,它与memcpy()行为相同。
void* memmove(
void* dest,
void* source,
size_t n
);
int a[100];
// ...
// 从数组成员a[1]开始的99个成员,都向前移动一个位置。
memmove(&a[0], &a[1], 99 * sizeof(int));
char x[] = "Home Sweet Home";
// 输出 Sweet Home Home
printf("%s\n", (char *) memmove(x, &x[5], 10));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# memcmp()
memcmp()函数用来比较两个内存区域。
int memcmp(
const void* s1,
const void* s2,
size_t n
);
// 它的返回值是一个整数。两块内存区域的每个字节以字符形式解读,按照字典顺序进行比较,
// 如果两者相同,返回0;如果s1大于s2,返回大于0的整数;如果s1小于s2,返回小于0的整数。
char* s1 = "abc";
char* s2 = "acd";
int r = memcmp(s1, s2, 3); // 小于 0
char s1[] = {'b', 'i', 'g', '\0', 'c', 'a', 'r'};
char s2[] = {'b', 'i', 'g', '\0', 'c', 'a', 't'};
if (memcmp(s1, s2, 3) == 0) // true
if (memcmp(s1, s2, 4) == 0) // true
if (memcmp(s1, s2, 7) == 0) // false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# memchr()
memchr()用于在内存区域中查找指定字符。
void* memchr(const void* s, int c, size_t n);
char *str = "Hello, world!";
char *p;
p = memchr(str, '!', 13); // p 指向感叹号的位置
1
2
3
4
5
6
2
3
4
5
6
# memset()
memset()将一段内存全部格式化为指定值。
void* memset(void* s, int c, size_t n);
char string1[15] = "BBBBBBBBBBBBBB";
// 输出 bbbbbbbBBBBBBB
printf("%s\n", (char*) memset(string1, 'b', 7));
memset(arr, 0, sizeof(arr));
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9