您的位置:首页 > 编程语言 > C语言/C++

【C++】学习笔记十八——循环和文本输入

2016-12-15 22:20 183 查看

循环和文本输入

逐字符的读取来自文件或键盘的文本。

1. 使用原始的cin进行输入

如果程序要使用循环来读取来自键盘的文本输入,则必须有办法知道何时停止读取。

一种方法是选择某个特殊字符——有时被称为哨兵字符(sentinel character),将其作为停止标记。

程序5.16

#include<iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters; enter # to quit:\n";
cin >> ch;
while (ch != '#')
{
cout << ch;
++count;
cin >> ch;
}
cout << endl << count << " characters read\n";
system("pause");
return 0;
}




程序5.16在遇到#时停止读取输入。该程序计算读取的字符数,并回显这些字符,即在屏幕上显示读取的字符。按下键盘上的键不能自动将字符显示到屏幕上,程序必须通过回显输入字符来完成这项工作。

程序在循环之前读取第一个第一个输入字符,这样循环可以测试第一个字符,因为第一个字符可能是#,这样程序能够正确地跳过整个循环。

如果读取到的第一个字符不是#,则程序进入该循环,显示字符,增加计数,然后读取下一个字符。

最后一步是极为重要的,没有这一步,循环将反复处理第一个输入字符,一直进行下去。有了这一步后,程序就可以处理到下一个字符。

结束循环的条件是最后读取的一个字符是#。该条件是通过在循环之前读取一个字符进行初始化的,而通过循环体结尾读取下一个字符进行更新。

程序在输出时省略了空格。cin在读取char值时,与读取其他基本类型一样,将忽略空格和换行符,因此输入中的空格没有被回显,也没有被包括在计数内。

发送给cin的输入被缓冲,只有在按下回车键后,输入的内容才会被发送给程序。这就是在运行该程序时,可以在#后面输入字符的原因。按下回车键后,整个字符序列将被发送给程序,但程序在遇到#字符后将结束对输入的处理。

2.使用cin.get(char)进行补救

通常,逐个字符读取输入的程序需要检查每个字符,包括空格、制表符和换行符。cin所述的istream类中包含一个能够满足这种要求的成员函数cin.get()。cin.get(ch)读取输入的下一个字符(即使它是空格),并将其赋给变量ch。

程序5.17

#include<iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters; enter # to quit:\n";
cin.get(ch);
while (ch != '#')
{
cout << ch;
++count;
cin.get(ch);
}
cout << endl << count << " characters read\n";
system("pause");
return 0;
}




程序5.17回显了每个字符,并将全部字符计算在内,包括空格。

3.文件尾条件

如果输入来自文件,可以使用一种功能更强大的技术——检测文件尾(EOF)——来表示输入结束。

很多操作系统都支持重定向(<),允许用文件替换键盘输入,还允许通过键盘来模拟文件尾条件。

如果编程环境能够检测到EOF,则可以在程序中使用重定向的文件。检测到EOF后,cin将两位(eofbit和failbit)都设置为1。可以通过成员函数eof()来查看eofbit是否被设置;如果检测到EOF,则cin.eof()将返回bool值true,否则返回false。同样,如果eofbit或failbit被设置为1,则fail()成员函数返回true,否则返回false。

程序5.18

#include<iostream>
int main()
{
using namespace std;
char ch;
int count = 0;
cin.get(ch);
while (cin.fail() == false)
{
cout << ch;
++count;
cin.get(ch);
}
cout << endl << count << " characters read\n";
system("pause");
return 0;
}




在windows系统上运行该程序,因此用【Ctrl+Z】和回车键来模拟EOF条件。

通过使用重定向,可以用该程序来显示文本文件,并报告它包含的字符数。

1. EOF结束输入

cin检测到EOF时,将设置cin对象中一个指示EOF条件的标记。设置这个标记后,cin将不读取输入,再次调用cin也不管用。

2.常见的字符输入做法

每次读取一个字符,直到遇到EOF的输入循环的基本设计如下:

cin.get(ch);
while (cin.fail() == false)
{
...
cin.get(ch);
}


可以将while改写为:

while (!cin.fail())


方法cin.get(char)的返回值是一个cin对象。然而,istream类提供了一个可以将istream对象(如cin)转换为bool值的函数:当cin出现在需要bool制的地方(如在while循环的测试条件中)时,该转换函数被调用。另外,如果最后一次读取成功了,则转换得到的bool值为true,否则为false。

因此上述while可改写为:

while (cin)


这比!cin.fail()或!cin.eof()更通用,因为它可以检测到其他失败原因,如磁盘故障。

由于cin.get(char)的返回值为cin,因此可以将循环精简为:

while (cin.get(ch))
{
...
}


这样,cin.get(char)只被调用一次,而不是两次(循环前一次、循环结束后一次)。

4. 另一个cin.get()版本

不接受任何参数的cin.get()成员函数返回输入中的下一个字符,因此,可以这样使用它:

ch = cin.get();


该函数的工作方式与C语言中的getchar()相似,将字符编码作为int值返回;而cin.get(ch)返回一个对象,而不是读取的字符。

同样,可以使用cout.put()参数来显示字符:

cout.put(ch);


该函数的工作方式类似于C语言中的putchar(),只不过其参数类型为char,而不是int。

程序5.19

#include<iostream>
int main(void)
{
using namespace std;
int ch;
int count = 0;

while ((ch = cin.get()) != EOF)
{
cout.put(char(ch));
++count;
}
cout << endl << count << " characters read\n";
system("pause");
return 0;
}




下表总结了cin.get(ch)和cin.get()的差别:

属性cin.get(ch)ch=cin.get()
传递输入字符的方式赋值给参数ch将函数返回值赋给ch
用于字符输入时函数的返回值istream对象(执行bool转换后为true)int类型的字符编码
到达EOF时函数的返回值istream对象(执行bool转换后为false)EOF
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++