24-使用原始的cin进行输入
5.5.1 使用原始的cin进行输入
如果程序要使用循环来读取来自键盘的文本输入,则必须有办法知道何时停止读取。如何知道这一点呢?一种方法是选择某个特殊字符—— 有时被称为哨兵字符(sentinel character),将其作为停止标记。例如,程序清单5.16在遇到#字符时停止读取输入。该程序计算读取的字符数,并回显这些字符,即在屏幕上显示读取的字符。按下键盘上的键不能自动将字符显示到屏幕上,程序必须通过回显输入字符来完成这项工作。通常,这种任务由操作系统处理。运行完毕后,该程序将报告处理的总字符数。程序清单5.16列出了该程序的代码。
程序清单5.16 textin1.cpp
// textin1.cpp -- reading chars with a while loop
#include <iostream>
int main()
{
using namespace std;
char ch;
int count = 0; // use basic input
cout << "Enter characters; enter # to quit:\n";
cin >> ch; // get a character
while (ch != ‘#’) // test the character
{
cout << ch; // echo the character
++count; // count the character
cin >> ch; // get the next character
}
cout << endl << count << " characters read\n";
return 0;
}
下面是该程序的运行情况:
see ken run#really fast
seekenrun
9 characters read
程序说明
请注意该程序的结构。该程序在循环之前读取第一个输入字符,这样循环可以测试第一个字符。这很重要,因为第一个字符可能是#。由于textin1.cpp使用的是入口条件循环,因此在这种情况下,能够正确地跳过整个循环。由于前面已经将变量count设置为0,因此count的值也是正确的。
如果读取的第一个字符不是#,则程序进入该循环,显示字符,增加计数,然后读取下一个字符。最后一步是极为重要的,没有这一步,循环将反复处理第一个输入字符,一直进行下去。有了这一步后,程序就可以处理到下一个字符。
注意,该循环设计遵循了前面指出的几条指导原则。结束循环的条件是最后读取的一个字符是#。该条件是通过在循环之前读取一个字符进行初始化的,而通过循环体结尾读取下一个字符进行更新。
上面的做法合情合理。但为什么程序在输出时省略了空格呢?原因在cin。读取char值时,与读取其他基本类型一样,cin将忽略空格和换行符。因此输入中的空格没有被回显,也没有被包括在计数内。
更为复杂的是,发送给cin的输入被缓冲。这意味着只有在用户按下回车键后,他输入的内容才会被发送给程序。这就是在运行该程序时,可以在#后面输入字符的原因。按下回车键后,整个字符序列将被发送给程序,但程序在遇到#字符后将结束对输入的处理。