今天看书的时候突然想明白了从键盘输入信息然后发送到程序时怎样的一个过程,之前一直想不明白,在此记录一下我的想法。
首先看一个程序:
<span style="font-size:12px;">#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 << endl; count++; cin >> ch; } cout << endl << count << "characters read\n"; system("pause"); return 0; } </span>这是C++ Primer Plus 那本书里面的程序,该程序使用循环来读取来自键盘的文本输入,当遇到#字符的时候停止读取。下面是该程序的运行情况:
在按ENTER键之前,我们可以往程序中输入任意多的字符,然后输入ENTER键才能回显字符。按下键盘上的字符键并不能直接将字符发送给程序,只有按下ENTER键之后才可以将之前输入的字符发送到输入队列里面去,然后程序中的cin从输入队列中获取字符。这就是在运行该程序时,可以在#后面输入字符的原因(输入#之后没有按ENTER键的话,所输入的字符并没有在输入队列中,程序还没有开始处理字符,只有按下ENTER键之后输入队列中才有了字符,cin才能从输入队列中获取,才开始对字符进行处理)。
我们在按下ENTER键之前,输入队列为空,所以cin获取不到字符,所有就会等待输入队列里面有字符了cin才能获取到字符,程序才能接着运行。我们在按下ENTER键之后,see ken run#really fast一起被发送到输入队列里面去,这个时候cin就可以从输入队列里面获取字符,首先获取s,然后进入while循环,将s字符输出,然后while中的cin接着获取第二个字符e,然后接着处理。直到遇到#字符,程序退出。#后面的字符really fast被留在输入队列中。
为了验证really fast是否被留在输入队列中,我们将程序改一下,用getline看能不能获取到输入队列中剩下的字符,程序如下:
<span style="font-size:12px;">#include <iostream> #include <string> using namespace std; int main() { char ch; int count = 0; cout << "Enter characters; enter # to quit:\n"; cin >> ch; while (ch != '#'){ cout << ch << endl; count++; cin >> ch; } cout << endl << count << " characters read\n"; string s; getline(cin, s); cout << "The remaining characters in queue: " << s<<endl; system("pause"); return 0; }</span>运行结果如下:
从运行结果我们可看出,really fast确实被留在了输入队列中,可以用getline将其从输入队列中取出来。
我们还发现程序在输出时忽略了空格,这是因为cin在读取char值时,与读取其他基本类型一样,cin将自动忽略空格和换行符。因此输入的空格没有回显,也没有被包括在计数内。
我们可以试一下每输入一个字符就按下ENTER键,运行结果如下图:
由运行结果我们可以看出,当每输入一个字符就按下ENTER键时,程序就会一个一个的处理字符。即输入s按下ENTER键,则操作系统将字符s发送到输入队列里面去,cin从输入队列里面获取到s,然后进入while循环,将s字符输出。因为这个时候输入队列中s字符已经被取出,输入队列为空,所以while循环中的cin就等待用户输入字符,并将字符发送到输入队列里面去,cin才可以从输入队列中取出下一个字符,然后接着处理。直到碰到#字符,程序退出。
总结:
并不是在键盘上按下字符键相应的字符就会直接发送给程序,而是从键盘上按下字符键之后在按下ENTER键,相应的字符才会被发送到输入队列中,程序中的cin才可以从输入队列中获取到字符。