C++primer第五版 编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分

 这是一个关于字符串处理的简单程序,但是里面有一些细节是值得关注的。先附上程序:

// primer_3_2_3.cpp : Defines the entry point for the application.
// 编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分

#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main()
{
	string str1;  //str1用来接收输入的字符串
	string str2("\0");  //str2用来存储处理后的字符串
	cout << "input a string:" << endl;
	while(getline(cin,str1))   //不断读取字符串
	{
		for(int i=0;i<str1.size();i++)  //遍历字符串的每一个元素
		{
			if(!ispunct(str1[i]))  //如果该元素不为标点符号
				str2+=str1[i];  //将该元素赋给str2
		}
		cout << str2 << endl;  //输出处理后的字符串
		str2="\0";  //将str2清空
		cout << "input a string:" << endl;
		string temp;  //如果不加这行及下一行代码,会导致getline将提示语“input a string”读进来
		getline(cin,temp);
	}
	system("pause");
	return 0;
}

再附上运行效果

1. 为了让程序能不断处理字符串,而不是每次只处理一个字符串就结束工作,我将读字符串的代码写进了while循环的判断条件里面。

2. 我使用了两个string对象,一个用来接收用户输入的原始字符串,一个用来存储按元素依次判断后的字符。其实用一个字符串加移位操作应该也能达到目的,但是我认为这样做会比较复杂。

3. string temp;  getline(cin,temp);  这两行代码可能有点莫名其妙,但如果不加这两行代码,会导致getline将提示语“input a string”读进来,即它的作用就是消耗掉提示语。

4. 在输入了一串字符串后,我们需要敲两次回车才能输出结果,原因就在于getline是按行读取,会将第一个回车读进来,如果没有第二个回车,getline(cin,str)还会等待输入。

这里我们可以简单测试一下

在while循环体最前面加一句 cout << "getline is over!" << endl; 如下

while(cin>>str1)   //不断读取字符串
	{
		cout << "getline is over!" << endl;
		for(int i=0;i<str1.size();i++)  //遍历字符串的每一个元素

然后运行,得到结果

扫描二维码关注公众号,回复: 2943601 查看本文章

看第一个输入,紧跟循环体的getline is over! 是在敲两个回车后才打印出来,可见之前getline(cin,str1)确实是在等待输入;然后又测试了换行之后继续输入,再次敲回车能打印结果,这也再次印证了getline的读取方式。

当然,如果我们将getline(cin,str1)改为cin>>str1,就不必那么麻烦了,直接输入完成后敲回车即可打印结果,即

	while(cin>>str1)   //不断读取字符串

但是cin读到空格处就结束了,因此如果是读一个单词,可以用cin,但是如果要读一行,还是得用getline。效果如下

另外,其实书上的意思是希望能用范围for语句来实现遍历,但是我用的VC6.0,而范围for是c++11的标准,vc6.0不支持此种用法,还有某些较低的vs版本也不支持此种用法。不过在此可以把范围for语句的用法写出来供大家参考(正确性还待验证哈)。

for(auto &c:str1)
{
	if(!ispunct(c))  //如果该元素不为标点符号
		str2+=c;  //将该元素赋给str2
}

最后,ispunct(c)函数是cctype头文件中的函数,当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)。cctype中还有很多常用的函数,现在列在下面,可按需取用

cctype头文件中的函数

isalnum(c)              当c是字母或数字时为真

isalpha(c)               当c是字母时为真

iscntrl(c)                 当c是控制字符时为真

isdigit(c)                 当c是数字时为真

isgraph(c)               当c不是空格但可以打印时

islower(c)               当c是小写字母时为真

isprint(c)                 当c是可打印字符时为真(即c是空格或c具有可视形式)

ispunct(c)               当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)

isspace(c)              当c是空白时为真(即c是空格、横向制表符、纵向制表符、回车符、换行符、进纸符中的一种)

isupper(c)               当c是大写字母时为真

isxdigit(c)                当c是十六进制数字时为真

tolower(c)               如果c是大写字母,输出对应的小写字母,否则原样输出c

toupper(c)               如果c是小写字母,输出对应的大写字母,否则原样输出c

猜你喜欢

转载自blog.csdn.net/elma_tww/article/details/82178915
今日推荐