C/C++字符串处理常用技巧
前言
由于在做题时,经常纠结到底该使用C还是C风格的字符串,而且对读入方式也比较纠结,所以写一篇blog来总结一下C/C中字符串处理的技巧。
C语言
与其说C语言的字符串是字符串,不如说是字符数组,C语言中对字符串的操作也大多依托于指针。
声明字符串
1 |
|
当然,由于C语言字符串本质上是字符串,也可以使用逐个字符赋值的方法,需要注意的是别忘记在行末加上结束符。
读入字符串
1. scanf
1 |
|
参数为想要读入的字符串的初地址,如果希望字符串下标从1开始,可以将参数改为str+1
使用该方式读入的特点:
- 遇到空格、回车会自动停止,并将其遗留在缓冲区中
- 自动为字符串添加结束符’\0’
scanf用于读取单个字符时需要特别注意
若想要使用循环来为字符串的各个字符赋值,由于缓冲区中不符合条件的字符会被scanf丢弃,所以不需要添加占位符,直接处理即可。但是,读取单个字符的情况并不会像读取字符串一样抛弃空格和换行,所以有如下代码的结果:
1 |
|
总而言之,当使用%s读取时,scanf会忽略回车和空格;使用%c读取时,不会忽略回车和空格,且要考虑scanf的占位符和缓冲区,所以用scanf读取单个字符时常常需要使用空格作为占位符
2.getchar
getchar的特点是不会抛弃如何字符,而是直接将缓冲区中的内容读入目标地址中。可以利用getchar的这一特点来清楚缓冲区中的换行。
3.gets
gets与scanf有如下不同的地方:
- gets会直接读取一整行,不会丢弃空格
- gets会将行末的回车符从缓冲区中取出并丢弃(而在结尾补上结束符),所以gets读完之后并不需要getchar来清理缓冲区。
4.fgets
函数原型:
1 |
|
其中size是读取的最大长度(不过通常不会填满,需要留出一位给结束符),当读取长度大于size时,多出来的长度会被截取;读取长度小于size时,fegts会将缓冲区中的换行符读入字符串(与gets不同),接下来的一个位置用结束符来填充。
第三个参数是文件指针,若从键盘读入,则用使用常数stdin
输出字符串
printf
正常输出,遇到停止符则不再输出,且不会自动添加换行符,当需要换行时,需要手动添加’\n’。
puts
输出完字符串后会自动再输出一个换行符。
处理字符串
1. strlen
1 |
|
计算字符串长度,遇到第一个停止符才算结束,若字符串不是以’\0’结束则会不停找下去。
2.1 strcat
1 |
|
strcat() 将把 arrayName2 连接到 arrayName1 后面,并删除原来 arrayName1 最后的结束标志’\0’。
2.2 strncat
1 |
|
与上述函数类似,但限制了拼接字符的个数。
3.1 strcpy
1 |
|
将字符串source复制到字符串dest中,并覆盖原始字符串,可以用来为字符串变量赋值。从首元素开始,遇到\0结束。
3.2 strncpy
1 |
|
将source字符串中前count个字符复制到dest中,并覆盖原始字符串。与strcpy不同的是,该函数只会更改前count个字符。
4.1 strcmp
按字典序比较字符串。
返回值为正数(未必为1),负数或0。
4.2 strncmp
按字典序比较前n个字符。
4.3 stricmp
按字典序(但忽略大小写)比较前n个字符。
5.1 strchr
1 |
|
返回指定字符在字符串中首次出现的地址,若想要利用此函数获取索引,则需要减去字符串的首地址,未找到则返回NULL。
5.2 strrchar
与上一个函数类似,但是从字符串尾部开始寻找。
5.3 strstr
1 |
|
在字符串str1中查找字符串str2的位置,若找到,则返回str2第一个字符在str1中的位置的指针,若没找到,返回NULL
6. atoi,atof,atol
分别是字符串转整型、浮点型、长整型。
遇到正负号或数字则开始转化,遇到非数字字符则停止。
7. strtok
1 |
|
类似python中的split方法,但是该函数将str中包含的所有delim子串转化成’\0’
8.sprintf
1 |
|
将format中(类似printf格式)的数据以字符串形式存到str中,该方法转化的字符串与使用printf的结果是一样的,只是不在屏幕上输出而已。尝尝用于想要将整型变量转化成字符串的情形。
9.sscanf
1 |
|
与sprintf相同但是方向相反,是将字符串中的数据读入到后续format代表的数据中。
C++
C在某种意义上可以看成C语言的扩展,所以上文提到的C语言风格字符串处理方式,在C中也可以用。另一方面,C++在C语言的基础上增加了类、流的概念,因此有了更多的操作空间。
声明字符串
1 |
|
读入字符串
cin
c++中可以用cin来为字符数组和string对象读取数据,cin的特性与scanf十分相似,都是遇到空格、换行停止,且会将最后的换行符留在缓冲区中。
不同的是,scanf不可以用于读入string对象。
cin.get
该函数有三种用法:
1 |
|
cin.getline
该函数有两个原型:
1 |
|
这两个函数与上文的cin.get看似相似,实则会从流中获得空格并丢弃。
输出字符串
这部分没什么好说的,似乎就比C多了一个cout。
处理字符串
这一部分主要介绍C++中string对象的成员函数,其中大部分成员函数的参数可以是string对象也可以是C的字符串指针。
1. length
用于获取该字符串的长度。
2. append
append方法对string对象进行原地修改。
1 |
|
3.substr
1 |
|
4. erase
与append一样,对string对象进行原地修改。
1 |
|
5.insert
同样是原地修改
1 |
|
6.compare
与C语言中strcmp的效果类似。
7.c_str
返回string对象的C字符串数组指针。
8. find与rfind
1 |
|
其中pos是起始的搜索位置,若未指定,则从头开始。
结语
C++和C语言风格的字符串有一些类似的地方,函数调用方法有很大不同,做题时特别需要注意的是读入字符串时回车是否会被取出并丢弃,否则会引发许多问题。
That’s all!