ITEEDU

11.7.8 设置及清除格式标志(flags、setiosflags、resetosflags)

无参数的成员函数flags只返回格式标志的当前设置(long类型的值)。带一个long类型参数的成员函数flags按参数指定的格式设置标志,返回以前的标志设置。flags的参数中未指定的任何格式都会被清除。图11.18的程序用成员函数flags设置新的格式状态和保存以前的格式状态,然后恢复原来的格式设置。

 // Fig. 11.28: fig11_28.cpp
 // Demonstrating the flags member function.
 #include <iostream.h>
 int main()
 {
   int i = 1000;
   double d = 0.0947625;
   cout << "The value of the flags variable is:"
       << cout.flags()
       << "\nPrint int and double in original format:\n"
       << i << '\t' << d << "\n\n";
   long originalFormat =
         cout.flags( ios::oct | ios::scientific );
   cout << "The value of the flags variable is:"
       << cout.flags()
       << "\nPrint int and double in a new format\n"
       << "specified using the flags member function:\n"
       << i << '\t' << d << "\n\n";
   cout.flags( originalFormat );
   cout << "The value of the flags variable is:"
       << cout.flags()
       << "\nPrint values in original format again:\n"
       << i << '\t' << d << endl;
   return 0;
 }

输出结果:

The value of the flags variable is: 0

Print int and double in original format:

1000 0.0947628

The value of the flags variable is: 4040

Print iht and double in a new format

Specified using the flags member function:

1750 9.476280e-002

The value of the flags variable is: 0

Print values in original format again:

1000 0.0947628

图 11.28 演示成员函数flags

成员函数serf设置参数所指定的格式标志,并返回long类型的标志设置值,例如:

long previousFlagSettings=

cout.setf(ios::showpoint | ios::showpos);

带两个long型参数的setf成员函数.例如:

cout.setf(ios::left,ios::adjustfield);

首先清除ios::adjustfield位,然后设置ios::left标志。该版本的setf用于与ios::basefield(用ios::dec、

ios::oct和ios::hex表示)、ios::floatfield(用ios::scientific和ios::fixed表示)和ios::adjustfiald(用ios::

left、ios::right和ios::internal表示)相关的位段。

成员函数unsetf清除指定的标志并返回清除前的标志值。

11.8 流错误状态

可以用类ios中的位测试流的状态。类ios是输入/输出类istream、ostream和iostream的基类。

当遇到文件结束符时,输人流中自动设置eofbit。可以在程序中使用成员函数eof确定是否已经到达文件尾。如果cin遇到了文件结束符,那么函数调用:

cin.eof()

返回true,否则返回false。

当流中发生格式错误时,虽然会设置failbit,但是字符并末丢失。成员函数fail判断流操作是否失败,这种错误通常可修复。

当发生导致数据丢失的错误时,设置badbit。成员函数bad判断流操作是否失败,这种严重错误通常不可修复。

如果eofbit、failbit或badbit都没有设置,则设置goodbit。

如果函数bad、fail和eof全都返回false,则成员函数good返回true。程序中应该只对“好”的流进行I/O操作。

成员函数rdstate返回流的错误状态。例如.函数调用cout.rdstate将返回流的状态,随后可以用一条switch语句测试该状态,测试工作包括检查ios::eofbit、ios::badbit、ios::failbit和ios::goodbit。

测试流状态的较好方法是使用成员函数eof、bad、fail和good,使用这些函数不需要程序员熟知特定的状态位。

成员函数clear通常用于把—个流的状态恢复为“好”,从而可以对该流继续执行I/O操作。由于clear的默认参数为ios::goodbit,所以下列语句:

cin.clear();

清除cin,并为流设置goodbit。下列语句:

cin.clear(ios::failbit)

实际上给流设置了failbit。在用自定义类型对cin执行输入操作或遇到问题时,用户可能需要这么做。clear这个名字用在这里似乎并不合适,但规定就是如此。

图11.29中的程序演示了成员函数rdstate、eof、fail、bad、good和clear的使用。

只要badbit和failbit中有一个被置位,成员函数operator!就返回true。只要badbit和failbit中有一个被置位,成员函数operator void*就返回false。这些函数可用于文件处理过程中测试选择结构或循环结构条件的true/false情况。

  // Fig. 11.29: fig11_29.cpp
 // Testing error states.
 #include <iostream.h>
 int main()
 {
   int x;
   cout << "Before a bad input operation:"
        << "\ncin.rdstate(): " << cin.rdstate()
       << "\n   cin.eof(): "<< cin.eof()
       << "In  cin.fail(): "<< cin.fail()
       << "\n   cin.bad(): " << cin.bad()
       << "\n  cin.good(): "<< cin.good()
       << "\n\nExpects an integer, but enter a character: ";
   cin >> x;
   cout << "\nEnter a bad input operation:"
       << "\ncin.rdstate(): "<< cin.rdstate()
       << "\n   cin.eof(): "<< cin.eof()
       << "\n  cin.fail(): " << cin.fail()
       << "\n   cin.bad(): "<< cin.badO
       << "\n  cin.geed()  " << cin.good() << "\n\n";
   cin.clear();
   cout << "After cin.clear()"
       << "\ncin.fail(): "<< cin.fail()
       << "\ncin.good(): "<< cin.good{) << endl;
   return 0;
 }

输出结果:

Before a bad input operation:

cin.rdstate(): 0

cin.eof(): 0

cin.fail() 0

tin.bad(): 0

cin.good(): 0

Expects an integer, but enter a character: A

After a bad input operation:

cin.eof(): 0

cin.fail(): 2

cin.bad(): 0

cin.good(): 0

After cin.clear()

cin. fail():0

cin.good(): 1

图 11.29 测试错误状态

11.9 把输出流连到输入流上

交互式应用程序通常要分别用类istream和ostream输入和输出数据。当提示信息出现在屏幕上时,用户输入一个数据来响应。显然,提示信息必须在执行输入操作前出现。在有输出缓冲区的情况下,只有在缓冲区已满时、在程序中明确地刷新输出缓冲区时或因程序结束而自动刷新输出缓冲区时,输出信息才会显示到屏幕上。为保证输出要在下一个输入前显示,C++提供了成员函数tie,该函数可以实现输入/输出操作的同步,也就是把这两个操作“系在一起”。例如,函数调用:

cin.tie(&cout);

把cout(ostream的对象)连到cin(istream的对象)上。实际上,C++为了建立用户的标准输入/输出环境而自动执行了这个操作,所以这个专门的调用其实是多余的。但是,用户可以显式地把其他配对的输入/输出流“系”在一起。使用函数调用:

inputStream.tie(0);

可以从一个输出流中解开输入流inputStream。