第十七章编程练习

本文提供了一系列C++编程练习,涵盖了输入输出流、文件复制、数据合并、容器操作及对象序列化等主题。通过实现不同功能的程序,如计算输入流字符数、复制文件内容、合并文本行、管理对象清单等,深入理解和应用C++的文件I/O和数据处理能力。
摘要由CSDN通过智能技术生成

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

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

int main(void)
{
    int cnt = 0;
    char ch;

    cout << "Enter a string:";
    while (cin.peek() != '$')
    {
        cin.get(ch); 
        cnt++;
    }
    cout << "count = " << cnt << endl;
    return 0;
}

2.编写一个程序,将键盘输入(直到模拟的文件尾)复制到通过命令行指定的文件中。
实现:

#include <iostream>
#include <fstream>
#include <cstdlib>
using std::cout;
using std::endl;
using std::ofstream;

int main(void)
{
    char ch;
    ofstream fout;
    fout.open("text.txt");
    if (fout.is_open())
    {
        cout << "Enter the data:";
        while (cin.get(ch) && ch != EOF)
        {
            fout << ch;
        }
    }
    else
    {
        cout << "Can't open / create the file" << endl;
        exit(0);
    }

    return 0;
}

3.编写一个程序,将一个文件复制到另一个文件中。让程序通过命令行获取文件名。如果文件无法打开,程序将指出这一点。
实现:

#include <iostream>
#include <fstream>
#include <cstdlib>
using std::endl;
using std::ofstream;
using std::ifstream;

int main(void)
{
    ifstream fin;
    ofstream fout;
    char ch;
    fin.open("text.txt");
    fout.open("text1.txt");

    while (fin.get(ch))
    {
        fout << ch;
    }

    fin.close();
    fout.close();

    return 0;
}

4.编写一个程序,它打开两个文本文件进行输入,打开一个文本文件进行输出。该程序将两个输入文件中对应的行并接起来,并用空格分隔,然后将结果写入到输出文件中。如果一个文件比另一个短,则将较长文件中余下的几行直接复制到输出文件中。例如,假设第一个输入文件的内容如下:

eggs kites donuts
balloons hammers
stones

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

zero lassitude
finance drama

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

eggs kites donuts zero lassitude
ballons hammers finance drama
stones

实现:

#include <iostream>
#include <fstream>
#include <string>
using std::endl;
using std::ofstream;
using std::ifstream;
using std::string;

int main(void)
{
    ifstream fin1;
    ifstream fin2;
    fin1.open("text1.txt");
    fin2.open("text2.txt");

    ofstream fout;
    fout.open("text3.txt");

    string str;

    while (!fin1.eof() || !fin2.eof())
    {
        if (getline(fin1, str) && str.size() > 0)
        {
            fout << str;
        }
        fout << " ";

        if (getline(fin2, str) && str.size() > 0)
        {
            fout << str;
        }
        fout << endl;
    }

    fin1.close();
    fin2.close();
    fout.close();


    return 0;
}

5.Mat和Pat想邀请他们的朋友来参加派对,就像第16章中的编程练习8那样,但现在他们希望程序使用文件。他们请您编写一个完成下述任务的程序。
从文本文件mat.dat中读取Mat朋友的姓名清单,其中每行为一个朋友。姓名将被存储在容器,然后按顺序显示出来。
从文本文件pat.dat中读取Pat朋友的姓名清单,其中每行为一个朋友。姓名将被存储在容器,然后按顺序显示出来。
合并两个清单,删除重复的条目,并将结果保存在文件matnpat.dat中,其中每行为一个朋友。
实现:

#include <iostream>
#include <fstream>
#include <string>
#include <set>
using std::endl;
using std::set;
using std::string;
using std::ifstream;
using std::ofstream;

int main(void)
{
    set<string> Mat, Pat, Guest;
    string name;

    ifstream fin1;
    ifstream fin2;
    ofstream fout;
    fin1.open("mat.txt");//Mat
    fin2.open("pat.txt");//Pat
    fout.open("matnpat.txt");

    while (getline(fin1, name) && name.size() > 0)
    {
        Mat.insert(name);
    }
    while (getline(fin2, name) && name.size() > 0)
    {
        Pat.insert(name);
    }

    Guest.insert(Mat.begin(), Mat.end());
    Guest.insert(Pat.begin(), Pat.end());

    for (auto pd = Guest.begin(); pd != Guest.end(); pd++)
    {
        fout << *pd << endl;
    }

    fin1.close();
    fin2.close();
    fout.close();

    return 0;
}

6.考虑14章的编程练习5中的类定义。如果还没有完成这个练习,请现在就做,然后完成下面的任务。
编写一个程序,它使用标准C++I/O、文件I/O以及14章的编程练习5中定义的employee、manager、fink、和highfink类型的数据。该程序应包含程序清单17.17中的代码行,即允许用户将数据添加到文件中。该程序首次被运行时,将要求用户输入数据,然后显示所有的数据,并将这些信息保存到一个文件中。当该程序再次被运行时,将首先读取并显示文件中的数据,然后让用户添加数据,并显示所有的数据。差别之一是,应通过一个指向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

实现:

//暂无

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 input.\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); // store characters

成员函数data()返回一个指针,该指针指向一个其中存储了字符串中字符的数组。它类似于成员函数c_str(),只是后者在数组末尾加上了一个空字符。
编写函数GetStr(),它根据文件恢复信息。该函数可以使用read()来获得字符串的长度,然后使用一个循环从文件中读取相应数量的字符,并将它们附加到一个原来为空的临时string末尾。由于string的数据是私有的,因此必须使用string类的方法来将数据存储到string对象中,而不能直接存储。
实现:

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
using std::ofstream;
using std::ifstream;

void ShowStr(const string& str);

class Store
{
private:
    ofstream &m_fout;

public:
    Store(ofstream& fout) : m_fout(fout) {}
    void operator()(const string& str);
};

void Store::operator()(const string& str)
{
    size_t len = str.size();
    m_fout.write((char*)&len, sizeof(len));
    m_fout.write(str.data(), len);
}

void GetStrs(ifstream& fin, vector<string> &v);

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 input.\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;
}


void ShowStr(const string&str)
{
    cout << str << endl;
}

void GetStrs(ifstream& fin, vector<string>& v)
{
    size_t len;
    char* pt;
    while (fin.read((char*)&len,sizeof(len)))//读取一行
    {
        pt = new char[len];
        fin.read(pt, len);
        v.push_back(pt);
        delete[]pt;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值