C语言字符串的处理总结

1.字符串的读取

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

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

(1).scanf()

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

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

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

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

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

#include 

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 ),定义于头文件

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

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

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

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

示例:

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

(3).gets()

函数原型:char * gets ( char * str ),定义于头文件

功能:从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起),定义于头文件

功能:从给定文件流读取最多 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 

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),定义于头文件

功能:从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符’\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 ),定义于头文件

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

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

返回值:返回 dest 的副本

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

示例:

#include 
#include 

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 ),定义于头文件

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

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

返回值:返回 dest 的副本

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

示例:

#include 
#include 

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 ),定义于头文件

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

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

返回值:返回 dest 的副本

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

示例:

#include 
#include 

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 ),定义于头文件

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

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

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

返回值:返回 dest 的副本

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

#include 
#include 

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 ),定义于头文件

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

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

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

#include 
#include 

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 ),定义于头文件

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

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

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

示例:

#include 
#include 

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 ),定义于头文件

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

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

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

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

示例:

#include 
#include 

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 ),定义在头文件

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

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

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

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

示例:

#include 
#include 

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 ),定义于头文件

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

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

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

#include 
#include 

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 ),定义在头文件

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

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

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

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

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

示例:

#include
#include

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.字符串转数值

数值抓换的所有函数都定义在 头文件中。

1.转浮点数

(1)atof()

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

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

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

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

示例:

#include
#include

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
#include

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
#include

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
#include

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 ),定义于头文件

功能:将字符转换为小写

参数:ch — 待转换的字符

返回值: ch 的小写

示例:

#include
#include 
#include 

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
#include 
#include 

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.字符分类

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

函数名 功能
isalnum 判断一个字符是否为字母或数字
isalpha 判断一个字符是否为英文字母
islower 判断一个字符是否为小写字母
isupper 判断一个字符是否为大写字母
isdight 判断一个字符是否为数字
isxdight 判断一个字符是否为十六进制的字符
iscntrl 判断一个字符是否为控制字符
isgraph 判断一个字符是否为可显示的字符
isspace 判断一个字符是否为空格
isblank (C99) 判断一个字符是否为空格字符
isprint 判断一个字符是否为可打印字符
ispunct 判断一个字符是否为标点符号

你可能感兴趣的:(C/C++,c语言)