练习说:
创建一个Text类,其中包含一个用于保存文本的字符串对象 一份文件。给它两个构造函数:默认构造函数和一个 采用字符串参数的构造函数,该参数是文件的名称 打开。使用第二个构造函数时,打开文件并阅读 将内容放入字符串成员对象中。添加成员函数 contents()返回字符串所以(例如)它可以打印。在 main(),使用Text打开文件并打印内容。
这是我写的课程:
class Text {
string fcontent;
public:
Text();
Text(string fname);
~Text();
string contents();
};
我还没有理解这项练习的所有内容。它要求创建一个函数contents()
,它返回一个字符串,但它没有说明函数必须做什么...
默认构造函数都不能做什么。
有人能帮助我吗?
答案 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
。