我知道有很多类似的问题,例如:
但是,我已经有一个类,它具有我不想破坏的特定行为,我想做的是向该类添加一个附加函数。
我正在使用的当前类是基本的TextFileReader
类,它继承自FileHandler
类。我将显示当前的类层次结构,以便您可以看到已有的类:您可以忽略所使用的ExceptionHandler
,因为它与该问题无关,但我将其保留在这里,因为这是定义类的方式。
FileHandler.h
#pragma once
#include <string>
#include <sstream>
#include <fstream>
namespace util {
class FileHandler {
protected:
std::fstream fileStream_;
std::string filePath_;
std::string filenameWithPath_;
private:
bool saveExceptionInLog_;
public:
virtual ~FileHandler();
FileHandler(const FileHandler& c) = delete;
FileHandler& operator=(const FileHandler& c) = delete;
protected:
FileHandler(const std::string& filename, bool saveExceptionInLog);
void throwError(const std::string& message) const;
void throwError(const std::ostringstream& streamMessage) const;
};
} // namespace util
FileHandler.cpp
#include "FileHandler.h"
#include "ExceptionHandler.h"
using namespace util;
FileHandler::FileHandler(const std::string & filename, bool saveExceptionInLog) :
saveExceptionInLog_(saveExceptionInLog),
filenameWithPath_(filename) {
// Extract path info if it exists
std::string::size_type lastIndex = filename.find_last_of("/\\");
if (lastIndex != std::string::npos) {
filePath_ = filename.substr(0, lastIndex);
}
if (filename.empty()) {
throw ExceptionHandler(__FUNCTION__ + std::string(" missing filename", saveExceptionInLog_));
}
}
FileHandler::~FileHandler() {
if (fileStream_.is_open()) {
fileStream_.close();
}
}
void FileHandler::throwError(const std::string & message) const {
throw ExceptionHandler("File [" + filenameWithPath_ + "] " + message, saveExceptionInLog_);
}
void FileHandler::throwError(const std::ostringstream & streamMessage) const {
throwError(streamMessage.str());
}
TextFileReader.h
#pragma once
#include "FileHandler.h"
namespace util {
class TextFileReader : public FileHandler {
public:
explicit TextFileReader(const std::string& filename);
virtual ~TextFileReader() = default;
TextFileReader(const TextFileReader& c) = delete;
TextFileReader& operator=(const TextFileReader& c) = delete;
std::string readAll() const;
};
} // namespace util
TextFileReader.cpp
#include "TextFileReader.h"
using namespace util;
TextFileReader::TextFileReader(const std::string & filename) :
FileHandler( filename, true ) {
fileStream_.open(filenameWithPath_.c_str(), std::ios_base::in);
if (!fileStream_.is_open()) {
throwError(__FUNCTION__ + std::string(" can not open file for reading"));
}
}
std::string TextFileReader::readAll() const {
std::ostringstream stream;
stream << fileStream_.rdbuf();
return stream.str();
}
我想做的或正在尝试做的就是将此方法添加到我的TextFileReader
std::vector<std::string> readLineByLine() const;
并且我已经尝试了在问题开始时上面列出的原始问答中的几种方法。
我遇到的一些问题是,在基类中,我存储的是fstream
对象,而不是ifstream
或ofstream
对象,因此尝试使用{{ 1}}在循环中不起作用。我试图直接从文件流句柄逐行读取。
在下一次尝试中,我尝试重用已经存在的std::getline
并将文件的所有内容读取到单个缓冲区中,并将其作为单个字符串返回,然后将该字符串解析为字符串向量。在我的while循环中,这种方法仍然无法使用readAll()
,因为它使用的是std::getline
对象,而不是ostringstream
对象。
该函数应该像这样工作-伪代码:
istringstream
这是我遇到的问题。有什么建议吗?
修改
我最初尝试使用用户的std::vector<std::string> TextFileReader::readLineByLine() const {
// get contents from file either line by line and store
// each line into a string and push that string into a
// vector of strings then return that vector after all
// lines have been read.
// or...
// read all contents from file into single string buffer and parse
// that string into a vector of strings and return that vector.
}
方法,但遇到此编译器错误:
Bapo's
但是用户评论说,如果我使1>------ Build started: Project: ChemLab, Configuration: Debug Win32 ------
1>TextFileReader.cpp
1>c:\...\textfilereader.cpp(24): error C2665: 'std::getline': none of the 2 overloads could convert all the argument types
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\string(160): note: could be 'std::basic_istream<char,std::char_traits<char>> &std::getline<char,std::char_traits<char>,std::allocator<char>>(std::basic_istream<char,std::char_traits<char>> &,std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\string(129): note: or 'std::basic_istream<char,std::char_traits<char>> &std::getline<char,std::char_traits<char>,std::allocator<char>>(std::basic_istream<char,std::char_traits<char>> &&,std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)'
1>c:\...\textfilereader.cpp(24): note: while trying to match the argument list '(const std::fstream, std::string)'
1>Done building project "ChemLab.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
可变,则const函数将不起作用。我继续将mutable修饰符添加到fileStream_
成员中,现在函数可以编译了。
答案 0 :(得分:2)
您可以执行以下操作:
std::vector<std::string> TextFileReader::readLineByLine() {
std::vector<std::string> return_vector{};
std::string line;
while(std::getline(fileStream_, line)) {
return_vector.push_back(line);
}
return return_vector;
}
但是,此后,您的整个流将被读取,并且将为“空”
编辑:忘记实际返回向量。