C++ Iostreams 用法详解(二)标准输入输出
首先说我们最常用的两个全局对象cin和cout,以下摘自MSDN:
You can then extract values from cin or wcin to read the standard input. The rules for doing so are outlined in the description of the class basic_istream Class. You can also insert values to cout or wcout to write the standard output. The rules for doing so are outlined in the description of the class basic_ostream Class.
可以看出,其中cin是istream的对象,可以从标准输入中提取数据,而cout是ostream的对象,可以向标准输出中输出数据。
什么是标准输入和标准输出呢?可能对于我们这些90后来说不是那么容易理解的,毕竟这是字符界面的概念,而我们在开始接触计算机的时候就已经是普遍的windows图形界面的操作系统了。但是windows操作系统还是为我们提供了一个模拟dos这种字符界面的程序cmd,让我们大致对这个有一定的了解。而在Linux系统中我们更容易说清楚这个概念:在执行一个shell命令时,会默认打开三个标准文件,即标准输入文件(stdin),通常对应终端的键盘;标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。
这样说比较了解了吧,因为我们在windows下面写一个win32 控制台应用程序的时候,其实我们的这个程序就是类似于Linux中执行在shell中的命令,所以这个程序在执行的时候当然可以带有参数(就是main函数的参数int argc和char* argv[]了),而且有标准输入缓冲区和标准输出缓冲区的概念了。只不过我们在windows下刚开始学习编程语言的时候,总是会用一些图形界面的IDE(例如VC++6.0就是我的启蒙IDE),所以对这个程序的运行机制并不是很清楚,只知道摁一下运行按键就自动完成了编译、连接、打开一个cmd并直接运行我们写的这个程序了。
有了标准输入和输出的概念(最好把他们像Linux里面一样看成是设备文件),接下来就要说一下这个cin和这个cout到底是怎么完成输入输出机制的了。首先来看一下下面这个例子:
#include <iostream>#include <string>
using namespace std;int main()
{int j = 0;
while(++j>0) for(int i=0;i>0;i++);string str;
cin >> str;cout << str << endl;system("pause");
}
用嵌套的循环来做了一个延时,当我们的程序(win32 控制台应用程序)在正常运行的时候,我们在键盘上敲下五个字符"hello",这个时候屏幕上并不会显示任何东西,因为虽然我们的输入都保存到了输入缓冲区中,但是我们并没有把它显示到屏幕上来。当我们第一次调用cin>>str的时候,这时其实是调用了cin这个istream对象的>>运算符的方法,它首先让我们的进程从运行(running)状态转换到等待I/O(waiting)状态,然后将输入缓冲区中的内容都输出到屏幕上来,这个时候我们刚才在键盘上按的hello就都显示出来了,然后当我们继续在键盘上按五个字符"world"的时候,输入缓冲区继续吸收我们输入的字符,然后被cin对象显示到屏幕上来,直到我们在键盘上按回车键(正常情况下)时,这时输入缓冲区也同时吸收了一个换行字符'\n',这个时候输入缓冲区中就有11个字符"helloworld\n"了,然后cin>>str开始将输入缓冲区中的这11个字符全部抽取(extract)出来存到对象cin的streambuf中(后面会讲到,这其实就是存储的buffer,而cin对象拥有的其实是streambuf对象的指针)。到这一步,还没有跟我们的str对象有任何关系,cin对象只是从标准输入输出中提取出了数据而已(这时我们可以理解为输入缓冲区中已经空了)。
之后的工作才关系到str对象,cin对象会根据str的类型(string)去格式化stream中的内容,即将前10个字符"helloworld"存到str对象中去,同时从streambuf中将这10个字符和结束字符'\n'清除(这其实是通过移动get指针来实现的,后面会说到),然后这条语句cin<<str;终于执行结束了。如果我们的代码改成
char str[20];
cin >> str;
char str1[20],str2[20];
cin.get(str1,20);cin.get(str2,20);