C语言字符串的处理总结

1.字符串的读取

字符的读取要注意以下几点:

  • 以什么作为结束标志,如空格、回车、EOF
  • 是否对溢出做检查
  • 是否包含结尾的空格或回车

(1).scanf()

函数原型:int scanf(const char * restrict format,…),定义于<stdio.h>头文件

功能:从标准输入流stdin (标准输入设备,一般指向键盘)中读内容的通用子程序,可以读入多个字符

格式说明符:%c 读取一个字符 %s读取一个字符串,以空格作为结束标志

返回值:scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF

注意:该函数读取到第一个空格之后就会结束读取,也就是用空格作为结束的标志。

#include <stdio.h>

int main()
{
	char name[40];
	printf("What's your name?\r\n");
	scanf("%s",name);
	printf("Hello,%s", name);
	return 0;
}

输入:Angela Plains
输出:Hello,Angela

(2).getc()

函数原型:int getc( FILE *stream ),定义于<stdio.h>头文件

功能:从给定的输入流读取下一个字符

参数:stream — 读取字符的来源

返回值:成功时为获得的字符,失败时为 EOF

注意:该函数一次只能读取一个字符,但是可以结合while循环多次读取

示例:

int main()
{
	char c;
	c= getc(stdin);  //从键盘读取
	printf("读取的字符为:%c", c);
	return 0;
}

(3).gets()

函数原型:char * gets ( char * str ),定义于<stdio.h>头文件

功能:从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在str指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。

参数: str — 指向存储字符串的数组指针

返回值:读入成功,返回与参数buffer相同的指针;读入过程中遇到EOF(End-of-File)或发生错误,返回NULL指针。所以在遇到返回值为 NULL的情况,要用ferror或feof函数检查是发生错误还是遇到EOF。

注意:可以读取空格,并且以换行符或EOF作为结束标志,读取内容中不包含换行符,特别要注意的是这个函数不做溢出检查

示例:

int main()
{
	char name[20];
	printf("What's your name?\r\n");
	gets(name);
	printf("Hello,%s", name);
	return 0;
}

(4).fgetc()

函数原型:int fgetc(FILE *stream),定义于,stdio.h>

功能:从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节

参数: stream — 读取字符的来源

返回值:成功时为获得的字符,失败时为 EOF。

示例:

int main()
{
	char ch;
	ch = fgetc(stdin);
	printf("读取的字符为:%c", ch);
	return 0;
}

(5).fgets()

函数原型:char *fgets( char *restrict str, int count, FILE *restrict stream ) (C99起),定义于<stdio.h>头文件

功能:从给定文件流读取最多 count - 1 个(最后要以’\0’结尾,所以是count-1)字符并将它们存储于 str 所指向的字符数组

参数:str — 指向char数组的指针

​ count — 写入的最大字符数,注意末尾的’\0’也要算入其中

​ stream — 读取数据来源的文件流

返回值:成功时为str,失败时为空指针

注意:count包含末尾的’\0’,如果输入的字符长度超过count,则会被截断,前count-1个字符存储到指定位置中,最后以’\0’结束。可以输入空格,以换行符来结束读取,但读取的内容中会包含换行符!

示例:

//从键盘读取
int main()
{
	char name[LENGTH];
	printf("What's your name?\r\n");
	fgets(name, LENGTH, stdin);
	printf("Hello,%s", name);
	return 0;
}
//从文件读入
#include <stdio.h>

int main(void)
{	
    FILE* fp;
    char str[60];

    /* 打开用于读取的文件 */
    fp = fopen("D:/Desktop/text.txt", "r");  //打开指定路径的文件
    if (fp == NULL) {
        perror("打开文件时发生错误");
        return(-1);
    }
    while(fgets(str, 60, fp) != NULL) {
        /* 向标准输出 stdout 写入内容 */
        printf("%s",str);
    }
    fclose(fp);

    return(0);
}

(6).小结

(1)scanf()和gets()函数都不会检查数据是否溢出,而fgets()会进行检查,当溢出时丢弃超出的数据
(2)scanf()遇到空格会停止读取,读取的内容不会包含空格;gets()函数遇到回车会停止读取,读取的内容不包含回车;fgets()函数遇到回车停止读取,但是读取的内容会包含回车键
(3)总结起来,个人认为fgets()最好用,但要注意其中包含回车。除此之外,该函数还能从文件中读取内容。

2.字符串的长度

(1).strlen()函数

函数原型:size_t strlen(const char* str),定义于头文件<stdio.h>

功能:从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符’\0’为止,然后返回计数器值(长度不包含’\0’)
参数:str — 字符串起始地址

返回值:字符串的长度,不包含’\0’

示例:

int main()
{
	char str[] = "Hello World!";
	int len = strlen(str);
	printf("%d\r\n",len);
	return 0;
}

输出结果为:12

(2).sizeof()

该函数用于字符串时,计算的是字符串常量所占用的长度(包括字符串本身的长度和\0),这也是和strlen的一个重要区别。

int main()
{
	char str[] = "Hello World!";
	int len = sizeof(str);
	printf("%d\r\n",len);
	return 0;
}

输出结果为:13

3.字符串复制

(1) strcpy()

函数原型:char *strcpy( char *restrict dest, const char *restrict src ),定义于<string.h>头文件

功能:复制 src 所指向的空终止字节字符串,包含空终止符,到首元素为 dest 所指的字符数组

参数:dest — 指向要写入的字符数组的指针 src — 指向要复制的空终止字节字符串的指针

返回值:返回 dest 的副本

注意:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串

示例:

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

int main(void)
{	
    char ch1[] = "Hello";
    char ch2[10];
    strcpy(ch2, ch1);
    printf("ch2:%s\r\n",ch2);
    return(0);
}

上面的代码执行之后,ch2[]中存放的内容是"Hello\0"。

(2).strncpy()

函数原型:char *strncpy( char *restrict dest, const char *restrict src, size_t count ),定义于<string.h>头文件

功能:复制 src 所指向的字符数组的至多 count 个字符(包含空终止字符,但不包含后随空字符的任何字符)到 dest 所指向的字符数组。

参数:dest — 指向要写入的字符数组的指针 src — 指向要复制的空终止字节字符串的指针 count — 要复制的最大字符数,包括’\0’

返回值:返回 dest 的副本

注意:如果不是将完整的 src 复制到dest 中,则需要在末尾添加终止符’\0’,否则字符串dest不完整。

示例:

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

int main(void)
{	
    char ch1[] = "Hello";
    char ch2[10];
    strncpy(ch2, ch1,2);
    ch2[2] = '\0';
    printf("%s\r\n", ch2);
    return(0);
}

上面的程序运行之后,ch[0] = ‘H’,ch[1] = ‘e’。
需要注意的是,strncoy()不会在末尾加上’\0’,需要手动加上,而strcpy()会自动加上。

4.附加字符串

(1).strcat()

函数原型:char *strcat( char *restrict dest, const char *restrict src ),定义于<string.h>头文件

功能:把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除*dest原来末尾的“\0”)

参数:dest — 指向要后附到的空终止字节字符串的指针 src — 指向作为复制来源的空终止字节字符串的指针

返回值:返回 dest 的副本

注意:dest末尾的\0会被覆盖,src末尾的\0会一起被复制过去,最终的字符串只有一个\0。

示例:

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

int main(void)
{	
    char ch1[20] = "Hello";
    char ch2[10] = " world!";
    strcat(ch1, ch2);
    printf("%s\r\n", ch1);
    return(0);
}

输出:Hello World!

(2).strncat()

函数原型:char *strncat( char *restrict dest, const char *restrict src, size_t count ),定义于<string.h>头文件

功能:从字符串src的开头拷贝n个字符到dest字符串尾部,dest要有足够的空间来容纳要拷贝的字符串。如果n大于字符串src的长度,那么仅将src全部追加到dest的尾部。

参数:dest — 指向要后附到的空终止字节字符串的指针 src — 指向作为复制来源的空终止字节字符串的指针

​ count — 要复制的最大字符数

返回值:返回 dest 的副本

注意:dest要有足够的空间来容纳要拷贝的字符串。如果n大于字符串src的长度,那么仅将src全部追加到dest的尾部。

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

int main(void)
{	
    char ch1[20] = "Hello";
    char ch2[10] = " world!";
    strncat(ch1, ch2,3);
    printf("%s\r\n", ch1);
    return(0);
}

输出:Hello wo(注意中间是有空格的)

5.字符串比较

(1).strcmp()

函数原型:int strcmp( const char *lhs, const char *rhs ),定义于<string.h>头文件

功能:以字典序比较二个空终止字节字符串

参数:lhs,rhs — 指向要比较的空终止字节字符串的指针

返回值:若字典序中 lhs 先出现于 rhs 则为负值;若 lhsrhs 比较相等则为零;若字典序中 lhs 后出现于 rhs 则为正值

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

int main(void)
{
    char *ch1 = "cb";
    char *ch2 = "ab";
    int res = strcmp(ch1, ch2);
    printf("%d\r\n", res);
    return(0);
}

(2) strncmp()

函数原型:int strncmp( const char *lhs, const char *rhs, size_t count ),定义于<string.h>头文件

功能:比较两个可能空终止的数组的至多 count 个字符。按字典序进行比较,不比较后随空字符的字

参数:lhs,rhs — 指向要比较的可能空终止的数组的指针 count — 要比较的最大字符数

返回值:若字典序中 lhs 先出现于 rhs 则为负值;若 lhsrhs 比较相等,或若 count 为零,则为零;若字典序中 lhs 后出现于 rhs 则为正值。

示例:

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

int main(void)
{
    char *ch1 = "abcdE";
    char *ch2 = "abcdF";
    int res = strncmp(ch1, ch2,4);
    printf("%d\r\n", res);
    return(0);
}

由于只比较前4个字符,所以输出为0,即相等。

6.字符串查找

(1).strchr()

函数原型:char *strchr( const char *str, int ch ),定义于<string.h>头文件

功能:寻找 ch (如同用 (char)ch 转换成 char 后)在 str 所指向的空终止字节字符串(转译每个字符为 unsigned char )中的首次出现位置。终止空字符被认为是字符串的一部分,并且能在寻找 ‘\0’ 时找到。

参数:str — 指向待分析的空终止字节字符串的指针 ch — 要搜索的字符

返回值:指向 str 找到的字符的指针,若未找到该字符则为空指针。

注意:虽然函数原型中 chint类型的,但是在传参第时候还是要传入字符,传入后会被强制转换为其对应的编码值。还有返回的是地址,不是在字符串中的相对位置。

示例:

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

int main(void)
{
    char *str = "abcdefg";
    char ch = 'd';
    char* addr = strchr(str, ch);
    printf("ch在str中的%d位置处(下标从0开始)!", (int)(addr - str));
    return(0);
}

(2).strrchr()

函数原型:char *strrchr( const char *str, int ch ),定义在<string.h>头文件

功能:寻找 ch (如同用 (char)ch 转换到 char 后)在 str 所指向的空终止字节串中(将每个字符转译成 unsigned char )的最后出现的位置。若搜索 ‘\0’ ,则认为终止空字符为字符串的一部分,而且能找到。

参数:str — 指向待分析的空终止字节字符串的指针 ch — 要搜索的字符

返回值:指向 str 中找到的字符的指针,或若找不到这种字符则为空指针。

注意:虽然函数原型中 chint类型的,但是在传参第时候还是要传入字符,传入后会被强制转换为其对应的编码值。还有返回的是地址,不是在字符串中的相对位置。(同strchr()函数)

示例:

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

int main(void)
{
    char *str = "dbcdefg";
    char ch = 'd';
    char* addr = strrchr(str, ch);
    printf("ch在str中的%d位置处(下标从0开始)!", (int)(addr - str));
    return(0);
}

(3)strstr()

函数原型:char *strstr( const char* str, const char* substr ),定义于<string.h>头文件

功能:查找 substr 所指的空终止字节字符串在 str 所指的空终止字节字符串中的首次出现位置。不比较空终止字符

参数:str — 指向要检验的空终止字节字符串的指针 substr — 指向要查找的空终止字节字符串的指针

返回值:指向于 str 中找到的子串首字符的指针,或若找不到该子串则为 NULL 。若 substr 指向空字符串,则返回 str

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

int main(void)
{
    char *str = "abcdefg";
    char *substr = "cd";
    char* addr = strstr(str, substr);
    printf("substr在str中的%d位置处(下标从0开始)!", (int)(addr - str));
    return(0);
}

7.字符串分割

strtok()

函数原型:char *strtok( char *restrict str, const char *restrict delim ),定义在<string.h>头文件

功能:分解字符串为一组字符串

参数:str — 指向待分割的字符串的指针 delim — 指向分隔符字符串或字符的指针

返回值:该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

实现原理:在 str字符串中找到分隔符,然后将其替换为’\0’,然后就结束了。注意即使 str中存在多个分割符,调用一次只要遇到一个分割符就会停止了,再进行一次调用就会替换第二个分割符,直到找不到分隔符则返回 NULL 。

注意:**strtok函数会破坏被分解字符串的完整,调用前和调用后的str已经不一样了。**在首次调用时,str指向要分解的字符串,之后再次调用要把str设成NULL。

示例:

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

int main(void)
{
    char str[] = "192.168.100.56";
    char delim[] = ".";  //以 '.'作为分隔符,注意要传入字符串而不是字符
    char* p;
    p = strtok(str, delim);
    printf("%s\r\n", p);
    while (p != NULL)
    {
        p = strtok(NULL, delim);
        printf("%s\r\n", p);
    }
    return 0;

}

输出如下:

192 168 100 56 (null)

其中"(null)"是当 p = NULL时进行打印输出的。

上面的示例需要注意以下几点:

  • 第6行的str要定义为字符串数组,如果定义定义为字符串指针会越界,原因未知
  • 第7行的分隔符是".",即是一个字符串而不是单独的一个 ‘.’ 字符,需要特别注意
  • 第9行第一次调用 strtok()函数,str要指向被分割的字符串的地址
  • 第13行开始的第2次及后面的调用,strtok()函数的第一个参数要传入 NULL

8.字符串转数值

数值抓换的所有函数都定义在 <stdlib.h>头文件中。

1.转浮点数

(1)atof()

函数原型:double atof( const char* str )

参数: str 要转换的字符串,如"3.1415"

返回值:转换得到的duoble类型的浮点数

注意:如果输入字符串中存在非法字符,则从非法字符开始的后面部分都为0,如"3.14a15"会被转换为3 .14。

示例:

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

int main(void)
{
    char str[] = "3.1415926";
    double f = atof(str);
    printf("%.10f\n", f);  //要用 .10f 来指定输出的小数位数,默认输出6为小数
    return 0;
}

(2)strtof(), strtod(), strtold()

函数原型:float strtof( const char *restrict str, char **restrict str_end );

​ double strtod( const char *restrict str, char **restrict str_end );

​ long double strtold( const char *restrict str, char **restrict str_end );

参数: str — 指针待转换的字符串的指针 str_end — 指向指向字符指针的指针

返回值:转换结果

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

int main(void)
{
    char str[] = "3.1415926 This is a test!";
    char* ptr;
    double f= strtof(str,&ptr);
    printf("数字部分为:%.10f\n", f);
    printf("字符串部分为:%s",ptr);
    return 0;
}

输出结果如下:

数字部分为:3.1415925026 字符串部分为: This is a test!

2.转整数

(1) atoi()、atil()、atoll()

函数原型:int atoi( const char *str ); long atol( const char *str ); long long atoll( const char *str );

参数:指向待转换的字符串的指针

返回值:分别为int型、long int型、long long int型

示例:

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

int main(void)
{
    char str[] = "1024";
    int inter = atoi(str);
    printf("%d\n", inter);
    return 0;
}

(2) strtol()、strtoll()

函数原型:long strtol( const char *restrict str, char **restrict str_end, int base );

long long strtoll( const char *restrict str, char **restrict str_end, int base );

参数:str — 指向待转换的字符串的指针

​ str_end — 对类型为 char* 的对象的引用,其值由函数设置为 str 中数值后的下一个字符,为指针的指针

​ base — 基数,必须介于 2 和 36(包含)之间,或者是特殊值 0,这个参数用于指定字符串中数字的进制

示例:

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

int main(void)
{
    char str[] = "1111 This is a test!";
    char* ptr;
    int inter = strtol(str,&ptr,2);
    printf("数字部分为:%d\n", inter);
    printf("字符串部分为:%s",ptr);
    return 0;
}

输出如下:

数字部分为:15 字符串部分为: This is a test!

(3) strtoul(), strtoull()

功能:将字符串转换为无符号整数值

这两个函数的用法与上面两个一致,区别在于转换结果是有符号还是无符号。

9.大小写转换

(1) 转小写 tolower()

函数原型:int tolower( int ch ),定义于<ctype.h>头文件

功能:将字符转换为小写

参数:ch — 待转换的字符

返回值: ch 的小写

示例:

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

int main(void)
{
    char str[] = "Hello World!";
    printf("转换前:%s\r\n", str);
    for (int i = 0; i < strlen(str); i++)
        str[i] = tolower(str[i]);
    printf("转换后:%s\r\n", str);
    return 0;
}

输出如下:

转换前:Hello World! 转换后:hello world!

(2)转大写 toupper()

函数原型:int toupper( int ch );

功能:将字符转换为大写

参数:ch — 待转换的字符

返回值: ch 的大写

示例:

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

int main(void)
{
    char str[] = "Hello World!";
    printf("转换前:%s\r\n", str);
    for (int i = 0; i < strlen(str); i++)
        str[i] = toupper(str[i]);
    printf("转换后:%s\r\n", str);
    return 0;
}

输出如下:

转换前:Hello World! 转换后:HELLO WORLD!

10.字符分类

这些函数使用都比较简单,这里只给出函数名和功能。这些函数实现的功能很简单,也可以自己实现。

<ctype.h>

函数名功能
isalnum判断一个字符是否为字母或数字
isalpha判断一个字符是否为英文字母
islower判断一个字符是否为小写字母
isupper判断一个字符是否为大写字母
isdight判断一个字符是否为数字
isxdight判断一个字符是否为十六进制的字符
iscntrl判断一个字符是否为控制字符
isgraph判断一个字符是否为可显示的字符
isspace判断一个字符是否为空格
isblank (C99)判断一个字符是否为空格字符
isprint判断一个字符是否为可打印字符
ispunct判断一个字符是否为标点符号
  • 5
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆昔z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值