字符串处理函数

8k 词

字符串处理函数

目录


字符串长度函数

strlen

1
2
3
4
5
6
7
8
9
10
11
12
#include <string.h>
size_t strlen(const char *str);
//size_t本质是unsigned int的typdef

/*
功能:
测传入的字符串指针str的字符串中字符的个数,不包括字符串结束符'\0'
参数:
str:字符串指针
返回值:
返回字符串的长度,不包括字符串结束符'\0'。
*/

sizeof函数不同,strlen返回的是字符串的长度;sizeof函数返回的是字符串开辟空间的大小,如果是一般的字符串常量,则这个空间大小就是字符串长度加上字符串结束符\0的大小,如果是字符数组的字符串,那就是数组大小。

字符串复制函数

strcpy

1
2
3
4
5
6
7
8
9
10
11
#include <string.h>
char *strcpy(char *dest, const char *src);
/*
功能:
将字符串src复制到字符串dest中
参数:
dest:目标字符串指针
src:源字符串指针
返回值:
返回目标字符串指针dest
*/

strcpy复制的字符串包含源字符串的\0,而且遇到的第一个\0会让函数结束复制并返回

注意:
在使用字符串复制函数时,函数不会检查dest的内存空间是否大于src,因此要保证目标字符串dest必须有足够的空间来存放源字符串src,否则会发生内存越界。

多个\0的情况

如果src有多个\0strcpy只会复制第一个\0之前的内容。

测试代码:[点击运行]

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

int main() {
char dest[50] = "Hello\0World";
char src[20] = " everyone!";

strcpy(dest, src);

printf("%s\n", dest);
}

输出结果:

output
1
everyone!

strncpy

1
2
3
4
5
6
7
8
9
10
11
12
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
/*
功能:
将字符串src的前n个字符复制到字符串dest中
参数:
dest:目标字符串指针
src:源字符串指针
n:要复制的字符个数
返回值:
返回目标字符串指针dest
*/

strncpy的返回条件不再是遇到\0,而是复制n个字符。n数完了就返回

注意:
如果n的大小大于src的大小,则在之后用\0填充dest
strncpy也要注意内存越界的问题。


字符串连接函数

strcat

1
2
3
4
5
6
7
8
9
10
11
#include <string.h>
char *strcat(char *dest, const char *src);
/*
功能:
将字符串src连接到字符串dest的末尾
参数:
dest:目标字符串指针
src:源字符串指针
返回值:
返回目标字符串指针dest
*/

strcat的追加位置是dest字符串的第一个\0前,如果dest字符串没有\0,则strcat会认为dest是一个尚未初始化的空间,则相当于直接给dest赋值src的内容。

注意:
strcat也要注意内存越界的问题

多个\0的情况

  1. 如果dest有多个\0strcat会覆盖掉第一个\0之后的内容。

    测试代码:[点击运行]

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

    int main() {
    char dest[50] = "Hello\0World";
    char src[20] = " everyone!";

    strcat(dest, src);

    printf("%s\n", dest);
    return 0;
    }

    输出结果:

    output
    1
    Hello everyone!
  2. 如果src有多个\0strcat只会追加src字符串第一个\0前的内容,而忽略src中后续的任何字符。
    测试代码:[点击运行]

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

    int main() {
    char dest[50] = "Hello ";
    char src[50] = "world\0again\0lastly";

    strcat(dest, src);

    printf("%s\n", dest);
    return 0;
    }

    输出结果:

    output
    1
    Hello world

strncat

1
2
3
4
5
6
7
8
9
10
11
12
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);
/*
功能:
将字符串src的前n个字符连接到字符串dest的末尾
参数:
dest:目标字符串指针
src:源字符串指针
n:要连接的字符个数
返回值:
返回目标字符串指针dest
*/

注意:
如果n大于src字符串中字符的个数(遇到第一个\0为止作为字符个数),则只将src字符串中第一个\0前的内容追加到dest指向的字符串之后。

测试代码:[点击运行]

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

int main() {
char dest[50] = "Hello ";
char src[50] = "world\0again\0lastly";

strncat(dest, src, 11);//显然在"again"之后的位置

printf("%s\n", dest);
return 0;
}

输出结果:

output
1
Hello world

字符串比较函数

strcmp

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string.h>
int strcmp(const char *str1, const char *str2);
/*
功能:
比较字符串str1和str2的大小
参数:
str1:字符串1指针
str2:字符串2指针
返回值:
如果str1 < str2,返回负数
如果str1 > str2,返回正数
如果str1 == str2,返回0
*/

比较规则:

  1. 从两个字符串的第一个字符开始比较ASIIC码,如果相等,则比较下一个字符,直到遇到不相等的字符或者遇到\0为止。
  2. 如果两个字符串相等,则返回0。
  3. 如果str1字符串大于str2字符串,返回1
  4. 如果str1字符串小于str2字符串,返回-1

注意:
strcmp返回值为0反而是两个字符串相同,需要注意。

测试代码:[点击运行]

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

int main() {
char str1[50] = "Hello";
char str2[50] = "World";
int result = strcmp(str1, str2);

printf("strcmp result: %d\n", result);
return 0;
}

输出结果(具体值可能和编译器有关):

output
1
strcmp result: -15

strncmp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <string.h>
int strncmp(const char *str1, const char *str2, size_t n);
/*
功能:
比较字符串str1和str2的前n个字符的大小
参数:
str1:字符串1指针
str2:字符串2指针
n:要比较的字符个数
返回值:
如果str1 < str2,返回负数
如果str1 > str2,返回正数
如果str1 == str2,返回0
*/

注意:
如果n大于str1str2字符串中字符的个数(遇到第一个\0为止作为字符个数),则只比较到第一个\0为止。

测试代码:[点击运行]

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

int main() {
char str1[50] = "Hello";
char str2[50] = "Hello World";
int result = strncmp(str1, str2, 3);

printf("strncmp result: %d\n", result);
return 0;
}

输出结果:

output
1
strncmp result: 0

字符串查找函数

strchr

1
2
3
4
5
6
7
8
9
10
11
12
#include <string.h>
char *strchr(const char *str, int c);
/*
功能:
在字符串str中查找ASIIC码c对应的字符**第一次**出现的位置
参数:
str:字符串指针
c:要查找的字符(用int强转后传入)
返回值:
如果找到字符c,返回指向该字符的指针
如果未找到字符c,返回NULL
*/

测试代码:**[点击运行]**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <string.h>

int main() {
char str[50] = "Halo everyone!";
char *result = strchr(str, 'e');

//打印返回的指针会显示查找到的第一个字符之后的内容
if(*result != NULL){
printf("strchr: found at %d\n", result-str);
printf("strchr result: %s\n", result);
}
else{
printf("strchr: not found\n");
}
return 0;
}

输出结果:

output
1
2
strchr: found at 5
strchr result: everyone!

strrchr

1
2
3
4
5
6
7
8
9
10
11
12
#include <string.h>
char *strrchr(const char *str, int c);
/*
功能:
在字符串str中查找ASIIC码c对应的字符**最后一次**出现的位置
参数:
str:字符串指针
c:要查找的字符(用int强转后传入)
返回值:
如果找到字符c,返回指向该字符的指针
如果未找到字符c,返回NULL
*/

测试代码:**[点击运行]**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <string.h>

int main() {
char str[50] = "Halo everyone!";
char *result = strrchr(str, 'e');

//打印返回的指针会显示查找到的第一个字符之后的内容
if(*result != NULL){
printf("strrchr: found at %d\n", result-str);
printf("strrchr result: %s\n", result);
}
else{
printf("strrchr: not found\n");
}
return 0;
}

输出结果:

output
1
2
strrchr: found at 13
strrchr result: e!

字符串匹配函数

strstr

1
2
3
4
5
6
7
8
9
10
11
12
#include <string.h>
char *strstr(const char *str1, const char *str2);
/*
功能:
在字符串str1中查找字符串str2**第一次**出现的位置
参数:
str1:字符串指针
str2:要查找的字符串
返回值:
如果找到字符串str2,返回指向该字符串的指针
如果未找到字符串str2,返回NULL
*/

测试代码:**[点击运行]**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <string.h>

int main() {
char str[50] = "Halo everyone!";
char *result = strstr(str, "Halo");

//打印返回的指针会显示查找到的第一个字符之后的内容
if(*result != NULL){
printf("strstr: found at %d\n", result-str);
}
else{
printf("strstr: not found\n");
}
return 0;
}

输出结果:

output
1
strstr: found at 0

字符串转换函数

atoi

将字符串转换为int类型,注意传入的字符串需要是纯数字字符串

其他的如atof、atol、atoll等函数同理,只不过返回值的数据类型不同,如atof是返回float类型,atol是返回long类型,浮点类型在转换的时候会四舍五入。

1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>
int atoi(const char *str);
/*
功能:
将字符串转换为整数
参数:
str:字符串指针
返回值:
转换后的整数
*/

测试代码:[点击运行]

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

int main() {
char str[50] = "12345";
int result = atoi(str);

printf("atoi: %d\n", result);
return 0;
}

输出结果:

output
1
atoi: 12345

字符串切割函数

strtok

字符串切割,按照delim指向的字符串中的字符,切割str指向的字符串。其实就是在str指向的字符串中发现了delim字符串中的字符,就将其变成\0,调用一次strtok只切割一次,切割一次之后,再去切割的时候strtok的第一个参数传NULL,意思是接着上次切割的位置继续切

注意:

  • strtok函数会改变原字符串,将切割的位置替换为\0,所以如果不想改变原字符串,需要先复制一份原字符串
  • 如果str中出现了连续几个delim的分隔符,则这一次切割会将这一段连续的分隔符替换为\0,所以并不是有多少个分隔符就切割多少次,而是有多少个非分隔符的字符串就切割多少次。
1
2
3
4
5
6
7
8
9
10
11
#include <string.h>
char *strtok(char *str, const char *delim);
/*
功能:
将字符串按照指定的分隔符进行切割
参数:
str:字符串指针
delim:分隔符
返回值:
返回指向切割后的字符串的指针
*/

测试代码:**[点击运行]**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <string.h>

int main() {
char str[50] = "1111:2222:3333::444";
char *result;
result = strtok(str, ":");
int i = 1;
//打印切下的第一片的结果
printf("times : %d , result: %s\n", i , result);


while (
(result = strtok(NULL, ":")) != NULL
){
i++;
//打印后续切割的字符片
printf("times : %d , result: %s\n", i , result);
}
return 0;
}

输出结果:

output
1
2
3
4
times : 1 , result: 1111
times : 2 , result: 2222
times : 3 , result: 3333
times : 4 , result: 444

字符串格式化函数

sprintf

将格式化的数据写入字符串中,类似于printf函数,只不过printf函数是将格式化的数据输出到屏幕上,而sprintf函数是将格式化的数据写入字符串中。功能上有点类似于strcpy函数。

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
/*
功能:
将格式化的数据写入字符串中
参数:
str:字符串指针
format:格式化字符串
...:可变参数
返回值:
返回写入的字符数
*/

测试代码:[点击运行]

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

int main() {
char str[50];
int a = 10;
float b = 3.14;
sprintf(str, "a = %d, b = %f", a, b);
printf("%s\n", str);
return 0;
}

输出结果:

output
1
a = 10, b = 3.140000

sscanf

竞赛中超级常用的函数,可以从buf中按照指定格式读取数据

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
/*
功能:
从字符串中按照指定格式读取数据
参数:
str:字符串指针
format:格式化字符串
...:可变参数
返回值:
返回读取的参数个数
*/

测试代码:[点击运行]

1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main() {
char str[50] = "a = 10, b = 3.14";
int a;
float b;
sscanf(str, "a = %d, b = %f", &a, &b);
printf("a = %d, b = %f\n", a, b);
return 0;
}

输出结果:

output
1
2
a = 10, b = 3.140000