资源描述
第八章 标准IO库
8.1 假设os是一个ofstream对象,下面程序做了什么?
os << “Goodbye!” << endl;
如果os 是ostringstream对象呢? 或者,os 是ifstream对象呢?
答:第一个,向文件中写入“Goodbye”, 第二个向string对象中写入“Goodbye”,第三个,如果os是一个ifstream对象,则错误,因为ifstream类中没有定义操作符 << 。
8.2 下面的声明是错误的,指出其错误并改正之: ostream print(ostream os);
答:标准库类型不允许做复制或赋值操作。形参或返回类型不能为流类型,所以上句代码错误,因为它把流类型的对象当做了形参。应改为传递指向该对象的指针或引用:
ostream &print( ostream &os );
8.3 编写一个函数,其唯一的形参和返回值都是istream&类型。该函数应一直读取流直到到达文件的结束符为止,还应将读到的内容输出到标准输出中。最后,重设流使其有效,并返回该流。
答:
// 定义控制台¬应用程序的入口点。
//
#include "stdafx.h"
#include "stdafx.h"
#include <iostream>
using namespace std;
istream & f( istream & in )
{
int ival;
while ( in >> ival, !in.eof()) // 遇到文件结束符之前一直读入数据
{
if(in.bad()) // input stream is corrupted; bail out, 流是否已被破坏
throw runtime_error("IO stream corrupted");
if ( in.fail() ) // bad input
{cerr << " bad date, try again:";
in.clear( ); // reset the stream
in.setstate(istream::eofbit); // 结束死循环
continue;
}
// process input
cout << ival << endl;
}
in.clear(); // 将n中的所有状态值都设为有效状态
return in;
}
int main()
{
cout << " Input some words ( ctrl + z to end ):\n";
f( cin );
system("pause");
return 0;
}
8.4 通过cin为实参实现调用来测试上题编写的函数。
8.5 导致下面的while循环终止的原因是什么?
while ( cin >> i ) //….
答:遇到了结束符;或者遇到了系统故障;读入了无效数据。
8.6 由于ifstream继承了istream,因此可将ifstream对象传递给形参为istream引用的函数。使用8.2节第一个习题编写的函数读取已命名的文件。
// 8.6.cpp : 定¡§义°?控?制?台¬¡§应®|用®?程¨¬序¨°的Ì?入¨?口¨²点Ì?。¡ê
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
istream & f( istream & is )
{
//int ival;
string ival;
while ( is >> ival, !is.eof()) // 遇®?到Ì?文?件t结¨¢束º?符¤?之?前¡ã一°?直¡À读¨¢入¨?数ºy据Y
{
if(is.bad()) // input stream is corrupted; bail out, 流¢¡Â是º?否¤?已°?被À?破?坏¦Ì
throw runtime_error("IO stream corrupted");
if ( is.fail() ) // bad input
{
cerr << " bad data, try again.";
is.clear( ); // reset the stream
is.setstate(istream::eofbit); // 结¨¢束º?死¨¤循-环¡¤
continue;
}
// process input
cout << ival << endl;
}
is.clear(); // 将?in中D的Ì?所¨´有®D状Á¡ä态¬?值¦Ì都?设¦¨¨为a有®D效¡ì状Á¡ä态¬?
return is;
}
int _tmain(int argc, _TCHAR* argv[])
{
string fName;
cout << " Input name of file( ctrl + z to end ):\n";
cin >> fName;
ifstream readfile;
readfile.open(fName.c_str()); // open the file
if (!readfile)
{
cerr << " error: cannot open the input file:" << fName << endl;
return -1;
}
f(readfile);
system("pause");
return 0;
}
8.7 本节所编写的两个程序,在打开vector容器中存放的任何文件失败时,使用break跳出while循环。重写这两个循环,如果文件无法打开,则输出警告信息,然后从vector中获取下一个文件名继续。
ifstream input;
vector<string>::const_iterator it = files.begin();
while ( it != files.end() )
{
input.open( it->c_str() );
if ( !input )
{
cerr << “¡ã error: can not open input file: “¡ã << *it << endl;
input.clear();
++it; // 获?取¨?下?一°?个?文?件t
continue; // 继¨¬续?处ä|理¤¨ª下?一°?个?文?件t
}
while ( input >> s )
process(s);
input.close();
input.clear();
++it;
}
8.8 上一个习题的程序可以不用continue语句实现。分别使用或不使用continue语句编写该程序。
不使用continue语句:
ifstream input;
vector<string>::const_iterator it = files.begin();
while ( it != files.end() )
{
input.open( it->c_str() );
if ( !input )
{
cerr << “¡ã error: can not open input file: “¡ã << *it << endl;
input.clear();
++it; // 获?取¨?下?一°?个?文?件t
}
else
{
while ( input >> s )
process(s);
input.close();
input.clear();
++it;
}
}
8.9 编写函数打开文件用于输入,将文件内容读入string类型的vector容器,每一行存储为该容器对象的一个元素。
// 8.9.cpp : 定义控制台¬应用程序的入口点
//
#include "stdafx.h"
#include < iostream >
#include < fstream >
#include < string >
#include < vector >
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string s;
ifstream input("test.txt"); // open the file
//cout << " Input files name:\n\t";
if ( !input ) // fail to open
{
cerr << " error: can not open input file: " << endl;
return -1;
}
// 打开后,将文件内容读入string类型的vector容器,每一行存储为
// 该容器对象的一个元素。
vector<string> fileWord;
while ( getline(input, s) )
{
fileWord.push_back(s);
//input.clear();
}
input.close(); // close the file
// 输出出来
vector<string>::const_iterator it = fileWord.begin();
while ( it != fileWord.end() )
{
cout << *it << endl;
++it; // 获取下一个文件
}
system("pause");
return 0;
}
8.10 重写上面的程序,把文件中的每个单词存储为容器的一个元素。
#include "stdafx.h"
#include < iostream >
#include < fstream >
#include < string >
#include < vector >
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string s;
ifstream input("test.txt"); // open the file
//cout << " Input files name:\n\t";
if ( !input ) // fail to open
{
cerr << " error: can not open input file: " << endl;
return -1;
}
// 打开后,将文件内容读入string类型的vector容器,每一行存储为
// 该容器对象的一个元素。
vector<string> fileWord;
while ( input >> s )
{
fileWord.push_back(s);
//input.clear();
}
// 输出出来
vector<string>::const_iterator it = fileWord.begin();
while ( it != fileWord.end() )
{
cout << *it << endl;
++it; // 获取下一个文件
}
system("pause");
return 0;
}
8.11 对于open_file函数,请解释为什么在调用open前先调用clear函数。如果忽略这个函数调用,会出现什么问题?如果在open后面调用clear函数,又会怎样?
此时不清楚通过形参In传进来的流对象的当前状态,所以在调用open前,先调用clear函数,将In置为有效状态。如果忽略,则in的原来的状态不会被清除,当用它打开另一个文件后,有可能导致对另一个文件的操作出现问题。
在open后调用clear函数,in都会被置为有效状态,从而为后续的文件操作带来问题。
8.12 对于open_file函数,请解释如果程序执行close函数失败,会产生什么结果?
会不能打开给定文件,因为open函数会检查流是否已经打开,如果打开,则设置内部状态指示发生了错误,接下来使用in的任何尝试都会失败。
8.13 编写类似open_file的程序打开文件用于输出。
// 8.13.cpp : 定义控制台应用程序的入口点
//
#include "stdafx.h"
#include < iostream >
#include < fstream >
#include < string >
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout << " input name of file you want to open:\n ";
string fName;
cin >> fName;
fstream fOpen;
fOpen.clear();
fOpen.open(fName.c_str()); // open the file
if ( !fOpen )
{
cerr << " cannot open the file given." << endl;
return -1;
}
string s;
while ( fOpen >> s )
{
cout << s << " ";
}
fOpen.close();
system("pause");
return 0;
}
8.14 使用open_file函数以及8,2节第一个习题编写的程序,打开给定文件并读取内容。
// 8.14.cpp : 定义控制台应用程序的入口点
//
#include"stdafx.h"
#include <iostream>
#include< fstream >
#include< string >
using namespace std;
istream & f( istream & in )
{
string ival;
while
( in >> ival, !in.eof()) // 遇到文件结束符之前一直读入数据
{ if(in.bad()) // input stream is corrupted; bail out, 流是否已被破坏
throw
runtime_error(
"IO stream corrupted"
);
if ( in.fail() ) // bad input
{
cerr <<
" bad date, try again:";
in.clear( ); // reset the stream
in.setstate(istream::eofbit); // 结束死循环
continue;
}
// process input
cout << ival << endl;
}
in.clear();
// 将in中的所有状态值都设为有效状态
return in;
}
int openFile( string fName )
{
fstream fOpen;
fOpen.clear();
fOpen.open(fName.c_str()); // open the file
if ( !fOpen )
{
cerr << " cannot open the file given." << endl;
return -1;
}
string s;
while ( fOpen >> s )
{
f( fOpen ); // 调用f()函数检测从文件中读入数据
cout << s << " ";
}
fOpen.close();
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << " input name of file you want to open:\n ";
string fName;
cin >> fName;
openFile( fName );
system("pause");
return 0;
}
8.15 使用8.2节第一个习题编写的函数输出istringstream对象的内容。
// 8.15.cpp :定义控制台应用程序的入口点
//
#include "stdafx.h"
#include <iostream>
#include < sstream>
#include < string >
using namespace std;
istream & f( istream & in )
{
string val;
while
( in >> val, !in.eof())
// 遇到文件结束符之前一直读入数据
{
if(in.bad()) // input stream is corrupted; bail out, 流是否已被破坏
throw runtime_error("IO stream corrupted");
if
( in.fail() ) // bad input
{
cerr << " bad date, try again:";
in.clear( ); // reset the stream
in.setstate(istream::eofbit); // 结束死循环
continue;
}
// process input
cout << val << "";
}
in.clear(); //将in中的所有状态值都设为有效状态
return in;
}
int _tmain(int argc, _TCHAR* argv[])
{
int val1 = 512, val2 = 1024;
ostringstream format_message;
format_message << " val1: " << val1 << " val2: " << val2 <<"\n";
istringstream input_istring( format_message.str() );
f( input_istring );
system("pause");
return 0;
}
8.16 编写程序将文件中的每一行存储在vector<string>容器对象中,然后使用istringstream从vector里以每次读一个单词的形式读取所存储的行。
// 8.16.cpp : 定义控制台应用程序的入口点
//
#include "stdafx.h"
#include < iostream >
#include < fstream >
#include < sstream >
#include < string >
#include < vector >
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string line, word;
ifstream input("test.txt"); // open the file
if ( !input ) // fail to open
{
cerr << " error: can not open input file: " << endl;
return -1;
}
// 打开后,将文件内容读入string类型的vector容器,每一行存储为
// 该容器对象的一个元素。
vector<string> fileWord;
while
( getline(input, line) )
{
fileWord.push_back(line);
//input.clear();
}
input.close(); // close the file 存储完毕
// 使用istringstream从vector里以每次读一个单词的形式读取所存储的行
vector<string>::const_iterator it = fileWord.begin();
while
( it != fileWord.end() )
{
istringstream divWord( *it );
// 将每行分解为每个单词输出来
while
( divWord >> word )
{
cout << word << " ";
}
cout << endl;
++it;
// 获取下一行
}
system("pause");
return 0;
}
展开阅读全文