《C++ Primer Plus》第17章:输入、输出和文件(7)

编程练习

  1. 编写一个程序计算输入流中第一个$之前的字符数目,并将$留在输入流中。

    #include<iostream>
    
    int main() {
        int ct = 0;
        while(std::cin.peek()!='$'){
            ct++;
            std::cin.get();
        }
        std::cout << "num: " << ct << std::endl;
    
        return 0;
    }
    

    答:

    #include<iostream>
    
    int main() {
        int ct = 0;
        while(std::cin.peek()!='$'){
            ct++;
            std::cin.get();
        }
        std::cout << "num: " << ct << std::endl;
    
        return 0;
    }
    
  2. 编写一个程序,将键盘输入(直到模拟的文件尾)复制到通过命令行指定的文件中。

    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main(int argc, char *argv[]){
        if(argc<2){
            std::cout << "Usage: " << argv[0] << " <filename>" << std::endl;
            exit(EXIT_FAILURE);
        }
        std::fstream fs;
        for(int file = 1; file < argc; file++){
            fs.open(argv[file], std::ios_base::out);
            if(!fs.is_open()){
                std::cerr << "error happens when open " << argv[file] << ".\n";
                exit(EXIT_FAILURE);
            }
            std::cout << "Please enter your input: \n";
            std::string input;
            getline(std::cin, input);
            while(input.size()>0){
                fs << input << std::endl;
                getline(std::cin, input);
            }
            fs.clear();
            fs.close();
    
            
            fs.open(argv[file], std::ios_base::in); 
            if(!fs.is_open()){
                std::cerr << "error happens when open " << argv[file] << ".\n";
                exit(EXIT_FAILURE);
            }
            std::cout << "The content of the " << argv[file] << ":\n";
    
            char ch;
            while(fs.get(ch)){
                std::cout << ch;
            }
            if(!fs.eof()){
                std::cerr << "error happens when read " << argv[file] << ".\n";
                exit(EXIT_FAILURE);
            }
    
            return 0;
        }
    }
    

    答:

    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main(int argc, char *argv[]){
        if(argc<2){
            std::cout << "Usage: " << argv[0] << " <filename>" << std::endl;
            exit(EXIT_FAILURE);
        }
        std::fstream fs;
        for(int file = 1; file < argc; file++){
            fs.open(argv[file], std::ios_base::out);
            if(!fs.is_open()){
                std::cerr << "error happens when open " << argv[file] << ".\n";
                exit(EXIT_FAILURE);
            }
            std::cout << "Please enter your input: \n";
            std::string input;
            getline(std::cin, input);
            while(input.size()>0){
                fs << input << std::endl;
                getline(std::cin, input);
            }
            fs.clear();
            fs.close();
    
            
            fs.open(argv[file], std::ios_base::in); 
            if(!fs.is_open()){
                std::cerr << "error happens when open " << argv[file] << ".\n";
                exit(EXIT_FAILURE);
            }
            std::cout << "The content of the " << argv[file] << ":\n";
    
            char ch;
            while(fs.get(ch)){
                std::cout << ch;
            }
            if(!fs.eof()){
                std::cerr << "error happens when read " << argv[file] << ".\n";
                exit(EXIT_FAILURE);
            }
    
            return 0;
        }
    }
    
  3. 编写一个程序,将一个文件复制到另一个文件中。让程序通过命令行获取文件名。如果文件无法打开,程序将指出这一点。

    //#include <cstdlib>
    #include<fstream>
    #include<iostream>
    #include<string>
    
    
    
    int main(int argc, char* argv[]){
        if(argc!=3){
            std::cout << "Usage: "  << argv[0] << " <target filename>  <sourse filename>.\n";
            exit(EXIT_FAILURE);
        }
        std::ofstream ofs;
        ofs.open(argv[1], std::ios_base::out);
        if(!ofs.is_open()){
            std::cerr << "Error happen when open " << argv[1] << ".\n";
            exit(EXIT_FAILURE);
        }
        std::ifstream ifs;
        ifs.open(argv[2], std::ios_base::in);
        if(!ifs.is_open()){
            std::cerr << "Error happen when open " << argv[2] << ".\n";
            exit(EXIT_FAILURE);
        }
        std::string line;
        getline(ifs,line);
        while(line.size()>0){
            ofs << line << std::endl;
            getline(ifs,line);
        }
        if(!ifs.eof()){
            std::cerr << "Error happens when read " << argv[1] << ".\n";
        }
    
        return 0;
    }
    

    答:

    //#include <cstdlib>
    #include<fstream>
    #include<iostream>
    #include<string>
    
    
    
    int main(int argc, char* argv[]){
        if(argc!=3){
            std::cout << "Usage: "  << argv[0] << " <target filename>  <sourse filename>.\n";
            exit(EXIT_FAILURE);
        }
        std::ofstream ofs;
        ofs.open(argv[1], std::ios_base::out);
        if(!ofs.is_open()){
            std::cerr << "Error happen when open " << argv[1] << ".\n";
            exit(EXIT_FAILURE);
        }
        std::ifstream ifs;
        ifs.open(argv[2], std::ios_base::in);
        if(!ifs.is_open()){
            std::cerr << "Error happen when open " << argv[2] << ".\n";
            exit(EXIT_FAILURE);
        }
        std::string line;
        getline(ifs,line);
        while(line.size()>0){
            ofs << line << std::endl;
            getline(ifs,line);
        }
        if(!ifs.eof()){
            std::cerr << "Error happens when read " << argv[1] << ".\n";
        }
    
        return 0;
    }
    
  4. 编写一个程序,它打开两个文本文件进行输入,打开一个文本文件进行输出。该程序将两个输入文件中对应的行并接起来,并用空格分隔,然后将结果写入到输出文件中。如果一个文件比另一个短,则将较长文件中余下的几行值复制到输出文件中。例如,假设第一个输入文件的内容如下:

    eggs kites donuts
    balloons hammers
    stones
    

    而第二个输入文件的内容如下:

    zero lassitude
    finance drama
    

    则得到的文件的内容将如下:

    eggs kites donuts zero lassitude
    balloons hammers finance drama
    stones
    

    答:

    #include <cstdlib>
    #include<iostream>
    #include<fstream>
    #include<string>
    
    using namespace std;
    
    int main(int argc, char* argv[]) {
    
        if(argc!=4){
            cerr << "Usage: " << argv[0] << " <source file1> <source file2> <target file>.\n";
            exit(EXIT_FAILURE);
        }
        ifstream ifs1(argv[1], ios_base::in);
        ifstream ifs2(argv[2], ios_base::in);
        ofstream ofs(argv[3], ios_base::out);
    
        if(!ifs1.is_open()) {
            cerr << "Error when open " << argv[1] << ".\n";
        }
        if(!ifs2.is_open()) {
            cerr << "Error when open " << argv[2] << ".\n";
        }
    
        string line1, line2;
        getline(ifs1, line1);
        getline(ifs2,line2);
        while(line1.size() >0 && line2.size() >0 ){
            ofs << line1 << ' ' << line2 << endl;
            getline(ifs1, line1);
            getline(ifs2,line2);
        }
        if(!ifs1.eof()){
            while(line1.size()>0){
                ofs << line1 << endl;
                getline(ifs1, line1);
            }
        }
        if(!ifs2.eof()){
            while(line2.size()>0){
                ofs << line2 << endl;
                getline(ifs2, line2);
            }
        }
    
        return 0;
    }
    
  5. Mat 和 Pat 想邀请他们的朋友来参加派对,就像第16章中的编程练习8那样,但现在他们希望程序使用文件。他们请您编写一个完成下述任务的程序。

    • 从文本文件 mat.dat 中读取 Mat 朋友的清单,其中每行为一个朋友。姓名将被存储在容器,然后按顺序显示出来。
    • 从文本文件 pat.dat 中读取 Pat 朋友的姓名清单,其中每行为一个朋友。姓名将被存储在容器,然后按顺序显示出来。
    • 合并两个清单,删除重复的条目,并将结果保存在文件 matnpat.dat 中,其中每行为一个朋友。

    答:

    #include <cstdlib>
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<vector>
    #include<set>
    
    
    int main() {
        using namespace std;
    
        ifstream matin("mat.dat", ios_base::in);
        ifstream patin("pat.dat", ios_base::in);
    
        if(!(matin && patin)){
            cerr << "Failed to open input files.\n";
            exit(EXIT_FAILURE);
        }
    
    
        ofstream matnpatout("matnpat.dat", ios_base::out);
        if(!matnpatout.is_open()){
            cerr << "Failed to open output files.\n";
            exit(EXIT_FAILURE);
        }
    
        vector<string> mat;
        vector<string> pat;
        string name;
    
        while(!matin.eof()) {       
            getline(matin, name);
            mat.push_back(name);
        }
        cout << "Success" << endl;
        while(!patin.eof()) {
            
            getline(patin, name);
            pat.push_back(name);
        }
    
        cout << "Mat's friends:\n";
        for(auto& name : mat){
            cout << name << endl;
        }
        cout << "Pat's friends:\n";
        for(auto& name : pat) {
            cout << name << endl;
        }
    
        set<string> matnpat;
        matnpat.insert(mat.begin(), mat.end());
        matnpat.insert(pat.begin(), pat.end());
        for(auto& name : matnpat) {
            matnpatout << name << endl;
        }
    
        return 0;
    }
    
  6. 编写一个程序,它使用标准 C++ I/O、文件 I/O 以及 14 章的编程练习5中定义的 employee、manager、fink 和 highfink 类型的数据。该程序应包含程序17.7中的代码行,即允许用户将新数据添加到文件中。该程序首次被运行时,将要求用户输入数据,然后显示所有数据,并将这些信息保存到一个文件中。当该程序再次被运行时,将首先读取并显示文件中的数据,然后让用户添加数据,并显示所有的数据。差别之一是,应通过一个指向 employee 类型的指针来处理数据。这样,指针可以指向 employee 对象,也可以指向从 employee 派生出来的其他三种对象中的任何一种。使数组较小有助于检查程序,例如,您可能将数组限定为最多包含 10 个元素:

    const int MAX = 10;		// no more than 10 objects
    ...
    employee * pc [MAX];
    

    为通过键盘输入,程序应使用一个菜单,让用户选择要创建的对象类型。菜单将使用一个 switch,以便使用 new 来创建指定类型的对象,并将它的地址赋给 pc 数组中的一个指针。然后该对象可以使用虚函数 setall() 来提示用户输入相应的数据:

    pc[i] -> setall();		// invokes function corresponding to type of object
    

    为将数据保存到文件中,应设计一个虚函数 writeall():

    for (i = 0; i < index; i++) {
    	pc[i] -> writeall(fout);		// fout ofstream connected to output file
    }
    

    注意:对于这个练习,应使用文本 I/O,而不是二进制 I/O(遗憾的是,虚对象包含指向虚函数指针表的指针,而 write() 将把这种信息复制到文件中。使用 read() 读取文件的内容,以填充对象时,函数指针将为乱码,这将扰乱虚函数的行为)。可使用换行符将字段分隔开,这样在输入时将很容易识别各个字段。也可以使用二进制 I/O,但不能将对象作为一个整体写入,而应该提供分别对每个类成员应用 write() 和 read() 的类方法。这样,程序将只把所需的数据保存到文件中。

    比较难处理的部分是使用文件恢复数据。问题在于:程序如何才能直到接下来要恢复的项目是 employee 对象、manager 对象、fink 对象还是 highfink 对象?一种方法是,在对象的数据写入文件时,在数据前面加上一个指示对象类型的数据。这样,在文件输入时,程序便可以读取该整数,并使用 switch 语句创建一个适当的对象来接收数据:

    enum classkind{Employee, Manager, Fink, Highfink};		// in class header
    ...
    int classtype;
    while((fin>>classtype).get(ch) ) { // newline separates int from data
    	switch(classtype) {
    		case Employee  	: pc[i] = new employee;
    						: break;
    

    然后便可以使用指针调用虚函数 getall() 来读取信息:

    pc[i++] -> getall();
    

    答:
    emp.h

    #ifndef EMP_H_
    #define EMP_H_
    
    #include<iostream>
    #include<fstream>
    #include<string>
    
    
    enum classkind {Employee, Manager, Fink, Highfink}; // in class header
    
    class ab_emp {;
    private:
        std::string fname;
        std::string lname;
        std::string job;
    public:
        ab_emp();
        ab_emp(const std::string & fn, const std::string & ln,
               const std::string & j);
        virtual void ShowAll() const;
        virtual void SetAll();
        virtual std::ofstream & WriteAll(std::ofstream & of) const;
        friend std::ostream & operator<<(std::ostream & os, const ab_emp & e);
        virtual ~ab_emp() = 0;
    };
    
    
    class employee : virtual public ab_emp {
    public:
        employee();
        employee(const std::string & fn, const std::string & ln,
                 const std::string & j);
        virtual void ShowAll() const;
        virtual void SetAll();
        std::ofstream & WriteAll(std::ofstream & of) const;
    };
    
    
    class manager : virtual public ab_emp {
    private:
        int inchargeof;
    protected:
        int InChargeOf() const {return inchargeof;}
        int & InChargeOf() {return inchargeof;}
    public:
        manager();
        manager(const std::string & fn, const std::string & ln,
                const std::string & j, int ico = 0);
        manager(const ab_emp & e, int ico);
        manager(const manager & m);
        virtual void ShowAll() const;
        virtual void SetAll();
        std::ofstream & WriteAll(std::ofstream & of) const;
    };
    
    class fink : virtual public ab_emp {
    private:
        std::string reportsto;
    protected:
        std::string ReportsTo() const { return reportsto;}
        std::string & ReportsTo() {return reportsto;}
    public:
        fink();
        fink(const std::string & fn, const std::string ln,
             const std::string & j, const std::string repo);
        fink(const ab_emp & e, const std::string repo);
        fink(const fink & f);
        virtual void ShowAll() const;
        virtual void SetAll();
        std::ofstream & WriteAll(std::ofstream & of) const; 
    };
    
    class highfink : public manager, public fink {
    public:
        highfink();
        highfink(const std::string & fn, const std::string & ln,
                 const std::string & j, const std::string & rpo,
                 int ico);
        highfink(const ab_emp & e, const std::string & rpo, int ico);
        highfink(const fink & f, int ico);
        highfink(const manager & m, const std::string & rpo);
        highfink(const highfink & h);
        virtual void ShowAll() const;
        virtual void SetAll();
        std::ofstream & WriteAll(std::ofstream & fout) const;
    };
    
    
    
    
    #endif
    

    emp.cpp

    #include"17-6_emp.h"
    #include <fstream>
    #include <ostream>
    #include <string>
    
    // ab_emp methods
    ab_emp::ab_emp() {
        fname = "none";
        lname = "none";
        job = "none";
    }
    
    ab_emp::ab_emp(const std::string & fn, const std::string & ln,
                   const std::string & j) : fname(fn), lname(ln), job(j)
    {
    }
    
    ab_emp::~ab_emp() {}
    
    
    void ab_emp::ShowAll() const {
        std::cout << "firstname: " << fname << std::endl;
        std::cout << "lastname: " << lname << std::endl;
        std::cout << "job: " << job << std::endl;
    }
    
    void ab_emp::SetAll() {
        std::cout << "Enter firstname: ";
        std::getline(std::cin, fname);
        std::cout << "Enter lastname: ";
        std::getline(std::cin, lname);
        std::cout << "Enter job: ";
        std::getline(std::cin, job);
    }
    
    std::ofstream & ab_emp::WriteAll (std::ofstream &of) const{
        of << fname << " " << lname << " " << job;
        return of;
    }
    
    std::ostream & operator<<(std::ostream & os, const ab_emp & e){
        os << e.fname << " " << e.lname << " " << e.job;
        return os;
    }
    
    
    // employee methods
    employee::employee(){}
    
    employee::employee(const std::string & fn, const std::string & ln,
                    const std::string & j): ab_emp(fn, ln, j)
    {
    
    }
    
    void employee::ShowAll() const {
        ab_emp::ShowAll();
    }
    
    void employee::SetAll() {
        ab_emp::SetAll();
    }
    
    std::ofstream & employee::WriteAll(std::ofstream &of) const {
        of << Employee << " ";
        ab_emp::WriteAll(of);
        return of;
    }
    
    
    // manager methods
    manager::manager() {
        inchargeof = 0;
    }
    
    manager::manager(const std::string & fn, const std::string & ln,
                     const std::string & job, int ico)
                     : ab_emp(fn, ln, job), inchargeof(ico)
    {
    }
    
    manager::manager(const ab_emp & e, int ico) : ab_emp(e), inchargeof(ico) {
    
    }
    
    manager::manager(const manager & m) : ab_emp(m), inchargeof(m.inchargeof){
    
    }
    
    void manager::ShowAll() const {
        ab_emp::ShowAll();
        std::cout << "InchargeOf: " << inchargeof << std::endl;
    }
    
    void manager::SetAll() {
        ab_emp::SetAll();
        std::cout << "Enter inchargeof: ";
        std::cin >> inchargeof;
        std::cin.get();
    }
    
    std::ofstream & manager::WriteAll(std::ofstream &of) const {
        of << Manager << " ";
        ab_emp::WriteAll(of) << " " << inchargeof;
        return of;
    }
    
    // fink methods
    fink::fink() {
        reportsto = "none";
    }
    
    fink::fink(const std::string & fn, const std::string ln,
               const std::string & job, const std::string repo) 
               : ab_emp(fn,ln,job), reportsto(repo)
    {
    
    }
    
    fink::fink(const ab_emp & e, const std::string repo)
            : ab_emp(e), reportsto(repo)
    {
    
    }
    
    fink::fink(const fink & f)
        : ab_emp(f) ,reportsto(f.reportsto)
    {
    }
    
    void fink::ShowAll() const
    {
        ab_emp::ShowAll();
        std::cout << "Reportsto: " << reportsto << std::endl;
    }
    
    void fink::SetAll()
    {
        ab_emp::SetAll();
        std::cout << "Enter reportsto: ";
        std::getline(std::cin, reportsto);
    }
    
    std::ofstream & fink::WriteAll(std::ofstream & fout) const
    {
        fout << Fink << " ";
        ab_emp::WriteAll(fout)<< " " << reportsto;
        return fout;
    }
    
    
    // highfink methods
    highfink::highfink(){}
    
    highfink::highfink(const std::string & fn, const std::string & ln,
                        const std::string & j, const std::string & repo, int ico)
                    : ab_emp(fn,ln,j), manager(fn,ln,j,ico), fink(fn,ln,j, repo)
    {
    
    }
    
    highfink::highfink(const ab_emp & e, const std::string & repo, int ico)
                    : ab_emp(e), manager(e,ico), fink(e,repo)
    {
    
    }
    
    highfink::highfink(const fink & f, int ico)
                    : ab_emp(f), fink(f), manager((const ab_emp &)f, ico)
    {
    
    }
    
    highfink::highfink(const manager & m, const std::string & repo)
                    : ab_emp(m), manager(m), fink((const ab_emp &)m, repo)
    {
    
    }
    
    highfink::highfink(const highfink & h)
                    : ab_emp(h), manager(h), fink(h)
    {
    
    }
    
    void highfink::ShowAll() const {
        ab_emp::ShowAll();
        
        std::cout << "ReportsTo: " << fink::ReportsTo() << std::endl;
        std::cout << "Inchargeof: "<< manager::InChargeOf() << std::endl;
    }
    
    void highfink::SetAll() {
        ab_emp::SetAll();
        std::cout << "Enter reportsto: ";
        std::getline(std::cin, fink::ReportsTo());
        std::cout << "Enter inchargeof: ";
        std::cin>>manager::InChargeOf();
        std::cin.get();
    }
    
    std::ofstream & highfink::WriteAll(std::ofstream &fout) const {
        fout << Highfink << " ";
        ab_emp::WriteAll(fout) << " " << fink::ReportsTo() << " " << manager::InChargeOf();
        return fout;
    }
    

    main.cpp

    #include"17-6_emp.h"
    #include <fstream>
    
    
    using namespace std;
    
    inline void showline(int n);
    void show_menu();
    inline void eatline();
    
    const int MAX = 10;
    
    int main() {
        ab_emp* pc[MAX];
        int ct; // number counter
    
        string fname, lname, job, reportsto;
        int inchargeof;
    
        // read from file
        ifstream fin("out.txt", ios_base::in);
        if(fin.is_open()){
            int kind;
            while(fin>>kind){
                switch (kind) {
                case Employee:
                    fin >> fname;
                    fin >> lname;
                    fin >> job;
                    pc[ct] = new employee(fname, lname, job);
                    break;
                case Manager:
                    fin >> fname;
                    fin >> lname;
                    fin >> job;
                    fin >> inchargeof;
                    pc[ct] = new manager(fname, lname, job, inchargeof);
                    break;
                case Fink:
                    fin >> fname;
                    fin >> lname;
                    fin >> job;
                    fin >> reportsto;
                    pc[ct] = new fink(fname, lname, job, reportsto);
                    break;
                case Highfink:
                    fin >> fname;
                    fin >> lname;
                    fin >> job;
                    fin >> reportsto;
                    fin >> inchargeof;
                    pc[ct] = new highfink(fname, lname, job, reportsto, inchargeof);
                    break;
                }
                ct++;
            }
            cout << "content in out.txt: " << endl;
            for(int i=0; i<ct; i++){
                pc[i]->ShowAll();
            }
            fin.close();
        }
    
    
    
        // add elements
        char choice;
    
        show_menu();
        while(cin>>choice && choice!='q' && ct<MAX){
            eatline();
            switch (choice) {
            case 'e':
                pc[ct] = new employee;
                pc[ct]->SetAll();
                break;
            case 'm':
                pc[ct] = new manager;
                pc[ct]->SetAll();
                break;
            case 'f':
                pc[ct] = new fink;
                pc[ct]->SetAll();
                break;
            case 'h':
                pc[ct] = new highfink;
                pc[ct]->SetAll();
                break;
            }
            ct++;
            show_menu();
        }
        for(int i=0 ; i<ct; i++){
            pc[i]->ShowAll();
        }
    
        // write to file
        ofstream fout("out.txt", ios_base::out);
        for(int i=0; i<ct; i++){
            pc[i]->WriteAll(fout);
            fout << endl;
        }
        fout.close();
    
        cout << "all contents written to out.txt\n";
    
        for(int i=0; i<ct;i++){
            delete pc[i];
        }
    
        return 0;
    
    }
    
    
    
    void show_menu(){
        ios_base::fmtflags old_fmt = cout.setf(ios_base::left, ios_base::adjustfield);
    
        showline(35);
        cout.width(20);
        cout << "e. employee";
        cout << "m. manager" << endl;
        cout.width(20);
        cout << "f. fink";
        cout << "h. highfink" << endl;
        cout << "q. quit" << endl;
        showline(35);
        cout << "Select a type: " << endl;
    
        cout.setf(old_fmt);
    }
    
    inline void showline(int n){
        cout.fill('-');
        cout.width(n);
        cout << "-" << endl;
        cout.fill(' ');
    }
    
    inline void eatline() {
        while(cin.get() != '\n') continue;
    }
    
  7. 下面是某个程序的部分代码。该程序将键盘输入读取到一个由 string 对象组成的 vector 中,将字符串内容(而不是 string 对象)存储到一个文件中,然后该文件的内容复制到另一个由 string 对象组成的 vector 中。

    int main() {
    	using namespace std;
    	vector<string> vostr;
    	string temp;
    	
    	// acquire strings
    	cout << "Enter strings (empty line to quit) : \n";
    	while (getline(cin, temp) && temp[0] != '\0' ) {
    		vostr.push_back(temp);
    	}
    	cout << "Here is your intput.\n ";
    	for_each(vostr.begin(), vostr.end(), ShowStr);
    
    	// store in a file
    	ofstream fout("strings.dat", ios_base::out | ios_base::binary);
    	for_each(vostr.begin(), vostr.end(), Store(fout));
    	fout.close;
    	
    	// recover file contents
    	vector<string> vistr;
    	ifstream fin("strings.dat", ios_base::in | ios_base::binary);
    	if (!fin.is_open() ) {
    		cerr << "Could not open file for input.\n";
    		exit(EXIT_FAILURE);
    	}
    	GetStrs(fin, vistr);
    	cout << "\nHere are the strings read from the file:\n";
    	for_each(vistr.begin(), vistr.end(), ShowStr);
    	
    	return 0;
    }
    

    该程序以二进制格式打开文件,并想使用 read() 和 write() 来完成 I/O。余下的工作如下所述。

    • 编写函数 void ShowStr(const string &),它显示一个 string 对象,并在显示完后换行。
    • 编写函数符 Store,它将字符串信息写入到文件中。Store 的构造函数应接受一个指定 ifstream 对象的参数,而重载的 operator()(const string &) 应指出要写入到文件中的字符串。一种可行的计划是,首先将字符串的长度写入到文件中,然后将字符串的内容写入到文件中。例如,如果 len 存储了字符串的长度,可以这样做:
      os.write((char *) &len, sizeof(std::size_t));		// store length
      os.write(s.data(), len);
      
      成员函数 data() 返回一个指针,该指针指向一个其中存储了字符串中字符的数组。它类似于成员函数 c_str(),只是后者在数组末尾加上了一个空字符。
    • 编写函数 GetStrs(),它根据文件恢复信息。该函数可以使用 read() 来获得字符串的长度,然后使用一个循环从文件中读取相应数量的字符,并将它们附加到一个原来为空的临时 string 末尾。由于 string 的数据是私有的,因此必须使用 string 类的方法来将数据存储到 string 对象中,而不能直接存储。

    答:

    #include <cstddef>
    #include <cstdlib>
    #include <ios>
    #include<iostream>
    #include<fstream>
    #include <ostream>
    #include<vector>
    #include<string>
    #include<algorithm>
    
    using namespace std;
    
    class Store {
    private:
        ostream &os;
    public:
        Store(ostream &o):os(o){}
        void operator()(const string & s){
            size_t len = s.length();
            os.write((const char *)&len, sizeof(std::size_t));
            os.write(s.data(),len);
        }
    };
    
    inline void ShowStr(const std::string& s) {
        cout << s << endl;
    }
    
    void GetStrs(std::ifstream & fin, std::vector<std::string> & vistr);
    
    int main(){
        using namespace std;
        vector<string> vostr;
        string temp;
    
        // acquire strings
        cout << "Enter strings (empty line to quit):\n";
        while(getline(cin, temp)&&temp.size()>0){
            vostr.push_back(temp);
        }
        for_each(vostr.begin(), vostr.end(), ShowStr);
    
        // store in a file
        ofstream fout("string.dat", ios_base::out|ios_base::binary);
        for_each(vostr.begin(), vostr.end(), Store(fout));
        fout.close();
    
        cin.get();
    
        // recover file contents
        vector<string> vistr;
        ifstream fin("string.dat", ios_base::in|ios_base::binary);
        if (!fin.is_open()){
            cerr << "Could not open file for input.\n";
            exit(EXIT_FAILURE);
        }
        GetStrs(fin, vistr);
        cout << "\nHere are the strings read from the file:\n";
        for_each(vistr.begin(), vistr.end(),ShowStr);
    
        return 0;
    
    }
    
    void GetStrs(std::ifstream & fin, std::vector<std::string> & vistr){
        size_t len;     // string length
        while(fin.read( (char*)&len, sizeof(size_t) ) ){
            string str;
            char ch;
            for(int i=0; i< len; i++){
                fin.read(&ch,sizeof(char));
                str.push_back(ch);
            }
            vistr.push_back(str);
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值