从思维C++中解决练习

Solving an exercise from Thinking C++

本文关键字:解决 练习 C++      更新时间:2023-10-16

练习说:

创建一个包含字符串对象的 Text 类,以保存 一个文件。给它两个构造函数:一个默认构造函数和一个 采用作为文件名的字符串参数的构造函数 以打开。使用第二个构造函数时,打开文件并读取 字符串成员对象中的内容。添加成员函数 content(( 返回字符串,以便(例如(可以打印它。在 main( (,使用文本打开文件并打印内容。

这是我写的类:

class Text {
    string fcontent;
    public:
        Text();
        Text(string fname);
        ~Text();
        string contents();
};

我还没有理解这个练习的所有内容。它要求创建一个函数contents(),返回一个字符串,但它没有说明函数必须做什么......默认构造函数也必须做什么.
有人可以帮助我吗?

该函数必须返回文件的内容,该文件(在您的情况下(存储在 fcontent 中。

    string Text::contents()
    {
      return fcontent;
    }

在这种情况下,默认构造函数不必执行任何操作。

    Text::Text(){}

编辑:看到下面有多少评论有新问题,我将在这里回顾并回答其余问题。

在 Text.h 中,您有:

    #ifndef TEXT_HH
    #define TEXT_HH
    #include <string> //[1] 
    class Text {
        std::string fcontent;//[2]
    public:
        Text();
        Text(std::string fname);
        ~Text();
        std::string contents();
    };
    #endif

和文本.cpp 有

    // Text.cpp
    #include "Text.h"
    #include <fstream>
    #include <iostream>
    #include <sstream>
    #include <string>
    using namespace std;
    Text::Text() {}
    Text::Text(string fname) {
        fstream f;
        f.open(fname.c_str(), ios::in);//[3]
        //[4]
        std::stringstream stream;
        while(true)
        {
            char buffer[1000];
            f.getline(buffer, 1000);
            if(f.good())
            {
                //This actually adds an extra newline at the end
                stream << buffer << 'n';
            }
            else
            {
                break;
            }
        }
        fcontent = stream.str();
        //remove extra newline
        fcontent.erase(fcontent.begin() + fcontent.size() - 1);
        f.close();//This is technically unnecessary, but not bad either
    }
    string Text::contents() {
        return fcontent;
    }
    Text::~Text() {}//[5]

第 1 点:头文件<string>包含 std::string 的类定义,即C++字符串。 这不应该与包含操作C字符串(const char *const char[]等(的函数的<cstring>混淆。

第 2 点:字符串类存在于 ::std 命名空间中,这意味着我们必须在每次需要该类时都使用 std::string,或者使用 using namespace std; 将此类拉入全局范围。 在头文件中,我们更喜欢前一种方法,因为 using 声明不会消失,这意味着包含此标头文件的每个头文件和源文件的命名空间都将更改,我们通常希望避免这种情况(即总是(。 但是,在 cpp 文件中,使用 using 声明没有问题,我们这样做了。

特点 3:fstreams 以 C 字符串作为文件名参数,我们可以从带有调用c_str()的C++字符串中获取对应的 C 字符串。 这将返回一个const char *

第 4 点:将整个文本文件读入字符串并不像看起来那么明显,因为流处理 eof(文件结束(和状态检查内容的方式。 简而言之,在设置eof标志之前,它会比你想要的多读一次(我知道,想要是主观的,但我认为已经足够接近了(。 这就是为什么在调用 get 之后和将读取的内容添加到我们的字符串流之前检查状态的原因。 流是一个相当复杂的主题,所以我不会在这里更详细地讨论它。

第 5 点:对象上的析构函数(非指针,就像我们的 fcontent(是自动调用的,所以我们不需要做任何事情来确保我们的 fcontent 字符串在 Text 对象被销毁时被销毁。 当我们用new动态分配某些东西时,当我们想要销毁它时,我们必须担心调用它delete