解决Thinking C ++中的练习

时间:2012-04-02 18:22:36

标签: c++

练习说:

  

创建一个Text类,其中包含一个用于保存文本的字符串对象   一份文件。给它两个构造函数:默认构造函数和一个   采用字符串参数的构造函数,该参数是文件的名称   打开。使用第二个构造函数时,打开文件并阅读   将内容放入字符串成员对象中。添加成员函数   contents()返回字符串所以(例如)它可以打印。在   main(),使用Text打开文件并打印内容。

这是我写的课程:

class Text {
    string fcontent;

    public:
        Text();
        Text(string fname);
        ~Text();

        string contents();
};

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

1 个答案:

答案 0 :(得分:1)

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

    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

和Text.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 ++字符串。这不应与<cstring>混淆,后者包含操作C字符串的函数(const char *const char[]等)。

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

第3点:fstreams将C字符串作为文件名参数,我们可以通过调用c_str()从C ++字符串中获取相应的C字符串。这会返回const char *

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

第5点:对象上的析构函数(非指针,如我们的fcontents)是自动调用的,因此我们不需要做任何事情来确保在销毁Text对象时销毁我们的fcontents字符串。当我们使用new动态分配内容时,当我们想要销毁它时,我们不得不担心在其上调用delete