C++ Primer(第四版)答案之第八章

8.1

将Goodbye!写入到文件(包括回车换行)。

如果os是ostringstream,则写入到字符串中。

如果os是ifstream,则错误

 

8.2

流对象不能赋值和复制,所以不能作为形参。修改为:

ostream print(ostream &os);

 

8.3

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

istream& func(istream& in) {
    int i;
    while(in>>i)
        cout << i << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    func(cin);

    return EXIT_SUCCESS;
}

注意:io标准库不允许构造对象,因此也不允许复制和赋值。

protected:
	basic_iostream()
	: __istream_type(), __ostream_type() { }

basic_iostream(const basic_iostream&) = delete;
basic_iostream& operator=(const basic_iostream&) = delete;

所以下面的代码会报错:error: 'std::basic_istream<_CharT, _Traits>::basic_istream() [with _CharT = char; _Traits = std::char_traits<char>]' is protected within this context

iostream mycin;

 

8.4

参见上题。

 

8.5

(a) fail,i是int,但输入了字符。

(b) eof, 遇到 Ctrl + D

(c) bad,遇到系统级流错误,不常见。

 

8.6

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

istream& func(istream& in) {
    string str;
    while(in>>str)
        cout << str << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    ifstream fin("Makefile");
    func(fin);
    fin.close();

    fin.open("CMakeCache.txt");
    func(fin);
    fin.close();

    return EXIT_SUCCESS;
}

 

8.7

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

istream& func(istream& in) {
    string str;
    while(in>>str)
        cout << str << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    vector<string> files;
    files.push_back(string("Makefile"));
    files.push_back(string("CMakeCache.txt"));
    ifstream fin;
    for(auto iter=files.begin(); iter!=files.end(); ++iter) {
        fin.open(iter->c_str());
        if(!fin) {
            cerr << "open file fail" << endl;
        } else {
            string line;
            while (fin >> line) {
                cout << line << endl;
            }
        }

        fin.close();
        fin.clear();
    }

    return EXIT_SUCCESS;
}

 

8.8

题目中提出使用continue语句,暗示了我们将流对象的定义放在loop里面

下面是用continue的代码,优点是不用管理流的状态,确定是每次循环都要创建流对象。

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

istream& func(istream& in) {
    string str;
    while(in>>str)
        cout << str << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    vector<string> files;
    files.push_back(string("Makefile"));
    files.push_back(string("CMakeCache.txt"));
    for(auto iter=files.begin(); iter!=files.end(); ++iter) {
        ifstream fin(iter->c_str());
        if(!fin) {
            cerr << "open file fail" << endl;
            continue;
        } 
        
        string line;
        while (fin >> line) {
            cout << line << endl;
        }
    }

    return EXIT_SUCCESS;
}

不用continue的版本如下:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

istream& func(istream& in) {
    string str;
    while(in>>str)
        cout << str << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    vector<string> files;
    files.push_back(string("Makefile"));
    files.push_back(string("CMakeCache.txt"));
    for(auto iter=files.begin(); iter!=files.end(); ++iter) {
        ifstream fin(iter->c_str());
        if(!fin) {
            cerr << "open file fail" << endl;
        } else {
            string line;
            while (fin >> line) {
                cout << line << endl;
            }
        }
    }

    return EXIT_SUCCESS;
}

 

8.9

这里需要特别注意的是,一次读取一行,要用getline,不能用输入操作符,输入操作符默认读取字符到空格、制表符、回车换位位置。而getline读取到回车换行位置。

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

istream& func(istream& in) {
    string str;
    while(in>>str)
        cout << str << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    vector<string> files;
    files.push_back(string("Makefile"));
    vector<string> data;
    for(auto iter=files.begin(); iter!=files.end(); ++iter) {
        ifstream fin(iter->c_str());
        if(!fin) {
            cerr << "open file fail" << endl;
        } else {
            string line;
            while (getline(fin, line))
                data.push_back(line);
        }

        for(auto iter=data.begin(); iter!=data.end(); ++iter)
            cout << iter->c_str() << endl;
    }

    return EXIT_SUCCESS;
}

 

8.10

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

istream& func(istream& in) {
    string str;
    while(in>>str)
        cout << str << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    vector<string> files;
    files.push_back(string("Makefile"));
    vector<string> data;
    for(auto iter=files.begin(); iter!=files.end(); ++iter) {
        ifstream fin(iter->c_str());
        if(!fin) {
            cerr << "open file fail" << endl;
        } else {
            string line;
            while (fin >> line)
                data.push_back(line);
        }

        for(auto iter=data.begin(); iter!=data.end(); ++iter)
            cout << iter->c_str() << endl;
    }

    return EXIT_SUCCESS;
}

 

8.11

之所以先调用clear函数,是不清楚形参in的状态,输入流对象有可能不是good状态,必须先clear,然后才能使用。如果放到open之后,如果状态不是good,open行为也必然失败,也就是文件打开失败。

 

8.12

如何close函数失败,那么仍然执行clear函数。之后,in的状态正常,打开下一个文件,上一个流关联的数据将丢失。

 

8.13

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

ifstream& open_file(ifstream& in, const string &filename) {
    in.close();
    in.clear();
    in.open(filename.c_str());
    return in;
}

int main() {
    // read file
    vector<string> files;
    files.push_back("Makefile");
    files.push_back("CMakeCache.txt");

    for(auto iter=files.begin(); iter!=files.end(); ++iter) {
        ifstream fin;
        open_file(fin, *iter);
        string line;
        while (getline(fin, line))
            cout << line << endl;
    }

    return EXIT_SUCCESS;
}

 

8.14

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

ifstream& open_file(ifstream& in, const string &filename) {
    in.close();
    in.clear();
    in.open(filename.c_str());
    return in;
}

istream& func(istream& in) {
    string line;
    while(getline(in, line))
        cout << line << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    // read file
    vector<string> files;
    files.push_back("Makefile");
    files.push_back("CMakeCache.txt");

    ifstream fin;
    for(auto iter=files.begin(); iter!=files.end(); ++iter) {
        open_file(fin, *iter);
        func(fin);
    }

    return EXIT_SUCCESS;
}

 

8.15

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

istream& func(istream& in) {
    int i;
    string tmp;
    while(in >> i >> tmp)
        cout << i << tmp << endl;
    printf("istream state=%d\n", in.rdstate());
    in.clear();
    cout << "after clear, state=" << in.rdstate() << endl;
}

int main() {
    ostringstream out;
    out << 1 << "|" << 2 << "|" << 3 << endl;
    istringstream in(out.str());
    func(in);

    return EXIT_SUCCESS;
}

 

8.16

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

int main() {
    // read file
    ifstream fin("Makefile");
    string s;
    vector<string> data;
    while (getline(fin, s))
        data.push_back(s);
    fin.close();

    for(auto iter=data.begin(); iter!=data.end(); ++iter) {
        istringstream is(iter->c_str());
        string word;
        while (is >> word)
            cout << word << endl;
    }

    return EXIT_SUCCESS;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值