《C++ Primer》第8章 IO库
C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO。这些类型支持从设备读取数据、向设备写入数据的IO操作,设备可以是文件、控制台窗口等。还有一些类型允许内存IO,即,从string读取数据,向string写入数据。IO库定义了读写内置类型值的操作。此外,一些类,如string,通常也会定义类似的IO操作,来读写自己的对象。
8.1 IO类习题答案
练习8.1:编写函数,接受一个istream&参数,返回值类型也istream&。此函数须从定流中读取数据,直至遇到文件结束标识时停止。它将读取的数据打印在标准输出上。完成这些操作后,在返回流之前,对流进行复位,使用其处于有效状态。
【出题思路】
本题是流的输入输出的基本练习。此外,本节介绍了流的条件状态,本题还对流的结束状态(本题是遇到文件结束符)、错误状态和数据错误状态(例如要求输入整数时输入了字符)的检测和处理进行了练习。
【解答】
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>//处理异常
using namespace std;
//不能拷贝IO对象,不能将形象或返回类型设置为流类型
istream& f(istream &in)//进行IO操作的函数通常以引用方式传递和返回值
{
int v;
while(in >> v, !in.eof())//直到遇到文件结束符才停止读取
{
if(in.bad())//不可恢复的错误,IO流崩溃
{
throw runtime_error("IO流错误");//抛出异常
}
if(in.fail())//可以恢复的错误; 比如输入类型不匹配
{
cerr << "数据错误,请重试:" << endl;
in.clear();//将in中所有条件状态位复位,将流的状态设置为有效,返回void, 恢复正常
in.ignore(100, '\n');//读取并忽略最多100个字符,包括'\n'
continue;
}
cout << v << endl;
}
in.clear();
return in;//返回引用
}//读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的;
int main()
{
cout << "请输入一些整数,按Ctrl+Z结束" << endl;
f(cin);
std::cout << "Hello, World!\n";
return 0;
}
运行结果:
练习8.2:测试函数,调用参数为cin。
【出题思路】
通过运行程序来观察流的状态如何产生变化。
【解答】
运行过程如下所示:
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>//处理异常
using namespace std;
//不能拷贝IO对象,不能将形象或返回类型设置为流类型
istream& f(istream &in)//进行IO操作的函数通常以引用方式传递和返回值
{
string v;
while(in >> v, !in.eof())//直到遇到文件结束符才停止读取
{
if(in.bad())//不可恢复的错误,IO流崩溃
{
throw runtime_error("IO流错误");//抛出异常
}
if(in.fail())//可以恢复的错误; 比如输入类型不匹配
{
cerr << "数据错误,请重试:" << endl;
in.clear();//将in中所有条件状态位复位,将流的状态设置为有效,返回void, 恢复正常
in.ignore(100, '\n');//读取并忽略最多100个字符,包括'\n'
continue;
}
cout << v << endl;
}
in.clear();
return in;//返回引用
}//读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的;
int main()
{
std::cout << "Hello, World!\n";
ios::sync_with_stdio(false);
cin.tie(NULL);
ostringstream msg;//字符串输出流, 向string写入数据
msg << "C++ Primer 第五版" << endl;
istringstream in(msg.str()); //返回msg所保存的string拷贝
f(in);
return 0;
}
运行结果:
练习8.3:什么情况下,下面的while循环会终止?
while(cin >> i) /*...*/
【出题思路】
进一步理解流的状态的检测方式。
【解答】
遇到文件结束符或者遇到了IO流错误,或者读入了无效数据循环会终止。