c++cin或cout对象包含一个描述流状态

1.流状态

cin或cout对象包含一个描述流状态(stream state)的数据成员(从ios_base那里继承的)。流状态(被定义为iostate类型,而iostate是一种bitmask类型)由3个ios_bae元素组成:eofbit、badbit或failbit,其中每个元素都是一位,可以是1(设置)或0(清除)。当cin操作到达文件末尾时,它将设置eofbit;当cin操作未能读取到预期的字符时,它将设置failbit。I/O失败(如试图读取不可访问的文件或试图写入到保护的磁盘),,也可能将failbit设置为1.在一些无法诊断的失败破坏流时,badbit元素将被设置。当全部3个状态都设置为0时,说明一切顺利。程序可以检查流状态,并使用这种信息来决定下一步做什么。

下表列出了这些位和一些报告或改变流状态的ios_base方法

上表中的两种方法——clear( )和setstate( )很相似。他们都重置状态,但采取的方式不同。clear( )方法将状态设置为它的参数。因此,下面的调用:

clear( );

将使用默认参数0,这里将清除全部3个状态位(eofbit、badbit和failbit)。同样,下面的调用:

clear(eofbit);

将状态设置为eofbit;也就是说,eofbit将被设置,另外两个状态位将被清除。 而setstate( )方法只影响其参数中已设置的位。因此,如果failbit被设置,则仍将被设置。

2.流状态的影响 只有在流状态良好(所有的位都被清除)的情况下,下面的if或while测试才能返回true:

while(cin>>input);

如果测试失败,可以使用上表中的成员函数来判断可能的原因。例如:

while(cin>>input){sum += input;}if(cin.eof())cout<<“Loop terminated because EOF encountered\n”;

设置流状态有一个非常重要的后果:流状态对后面的输入或输出关闭,知道位被清除。例如,下面的代码不能正常工作:

while(cin>>input){sum += input;}cin>>input;//won’t work

如果希望程序在流状态位被设置后能够读取后面的输入,就必须将流状态设置为良好(即为0)。这可以通过clear( )函数来实现:

whlie(cin>>input){sum += input;}cin.clear();while(!isspace(cin.get()))continue;cin>>input;

注意,这还不足以重新设置流状态。导致输入循环终止的不匹配输入仍留在输入队列中,程序必须跳过它。一种方法是已知读取字符,直到达到空白为止。isspace( )参数是一个cctype函数,它在参数是空白字符时返回true。另一种方法是,丢弃行中剩余部分,而不仅仅是下一个单词:

while(cin.get()!=’\n’)continue;//get rid rest of line

这个例子假设循环由于不恰当的输入而终止。现在,假设循环是由于达到文件尾或者由于硬件故障而终止的,则处理错误输入的新代码将毫无意义。可以使用fail( )方法检测假设是否正确,来修复问题。由于历史原因,fial( )在failbit或eofbit被设置时返回true,因此代码必须排除后一种情况。下面是一个排除这种情况的例子:

while(cin>>input){sum += input;}if(cin.fail() && !cin.eof()){cin.clear();while(!isspace(cin.get()))continue;}else{cout<<“I cannot go on!\n”;exit(1);}cin>>input;

3.其他istream类方法

1)单字符输入,cin.get(ch)与cin.get()

采用哪种单字符输入形式呢? 首先,应该确认是否希望跳过空白。如果跳过空白方便,则使用抽取操作符>>。如果希望检测每个字符,请使用get( )方法。

2)字符串输入:getline( )、get( )和ignore( )

istream & get(char *, int, char);istream & get(char *, int);istream & getline(char *, int, char);istream & getline(char *, int);

第一个参数是用于放置输入字符串的内存单元的地址。第二个参数比要读取的最大字符数大1(额外的一个字符用于存储结尾的空字符,以便将输入存储为一个字符串)。第三个参数指定用作分界符的字符,只有两个参数的版本将换行符作为分界符。上述函数都在读取最大数目的字符或遇到换行符后为止。 例如,下面的代码:

;cin.get(line,50);

将字符输入读取到字符数组line中。cin,get( )函数将在达到第49个字符或遇到换行符(默认情况)后停止将输入读取到数组中。get( )和getline( )之间的主要区别在于,get( )将换行符保留在输入流中,这样接下来的输入操作首先看到的将是换行符,而getline( )抽取并丢弃输入流中的换行符。 下面程序演示了getline( )和get( )是如何工作的,它还介绍了ignore( )成员函数。该函数接受两个参数:一个是数字,指定要读取的最大字符;另一个是字符,用作输入分界符。如:

ignore(255, ‘\n’);

将读取并丢弃接下来的255个字符或直到到达第一个换行符。原型为两个参数提供的默认值为1和EOF,该函数的返回类型为istream &:

istream & ignore(int = 1, int = EOF);

示例代码:

Limit = 255;int main(){using std::cout;using std::cin;using std::endl;char input[Limit];cout<<“Enter a string for getline()processing:\n”;cin.getline(input,Limit,’#’);cout<<“Here is your input: \n”;cout<<input<<“\nDone with phase 1\n”;char ch;cin.get(ch);cout<<“The next input character is “<<ch<<endl;if(ch != ‘\n’)cin.ignore(Limit,’\n’);cout<<“Enter a string for get()processing: \n”;cin.get(input,Limit,’#’);cout<<“Here is your input: \n”;cout<<input<<“\nDone with phase 2\n”;cin.get(ch);cout<<“The next input character is “<<ch<<endl;return 0;}

注意:getline( )函数将丢弃输入中的分界字符#,而get( )不会。

轻轻的风,吹开你紧锁的眉头,

c++cin或cout对象包含一个描述流状态

相关文章:

你感兴趣的文章:

标签云: