我想用C++将文本文件的全部内容读入std::string
对象。
使用Python,我可以写成:
text = open("text.txt", "rt").read()
这很简单又优雅。我不喜欢丑陋的东西,所以我想知道——用C++读取文本文件最优雅的方式是什么? 谢谢。
有许多方法,你可以选择最适合你的优雅方式。
读取 char*:
ifstream file ("file.txt", ios::in|ios::binary|ios::ate);
if (file.is_open())
{
file.seekg(0, ios::end);
size = file.tellg();
char *contents = new char [size];
file.seekg (0, ios::beg);
file.read (contents, size);
file.close();
//... do something with it
delete [] contents;
}
转换为 std::string:
std::ifstream in("file.txt");
std::string contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
转换为vector<char>:
std::ifstream in("file.txt");
std::vector<char> contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
使用 stringstream 转换为字符串:
std::ifstream in("file.txt");
std::stringstream buffer;
buffer << in.rdbuf();
std::string contents(buffer.str());
file.txt 只是一个例子,对二进制文件同样适用,只需确保在 ifstream 构造函数中使用 ios::binary。
// 做一些事情
delete[] contents;
} - Kevin Dill这个主题有另一个帖子。
我的解决方案来自于这个帖子(都是一行代码):
好的解决方案(见米兰的第二个方案):
string str((istreambuf_iterator<char>(ifs)), istreambuf_iterator<char>());
速度也很快:
string str(static_cast<stringstream const&>(stringstream() << ifs.rdbuf()).str());
string str((istreambuf_iterator<char>(ifs)));
对我来说运行良好,有什么问题吗? - Thomas Emax_size()
是相对于 size_t
的大小定义的,而 size_t
的大小又与您的平台的位数相关。这样定义是为了允许字符串的大小达到您的平台可以寻址的最大值。 - Devin Lane我喜欢米兰的char*方式,但使用std::string。
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
string& getfile(const string& filename, string& buffer) {
ifstream in(filename.c_str(), ios_base::binary | ios_base::ate);
in.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit);
buffer.resize(in.tellg());
in.seekg(0, ios_base::beg);
in.read(&buffer[0], buffer.size());
return buffer;
}
int main(int argc, char* argv[]) {
if (argc != 2) {
cerr << "Usage: this_executable file_to_read\n";
return EXIT_FAILURE;
}
string buffer;
cout << getfile(argv[1], buffer).size() << "\n";
}
(根据您是否希望换行符被翻译,可以使用或不使用ios_base::binary。您还可以将getfile更改为仅返回一个字符串,以便无需传递缓冲区字符串。然后,测试编译器在返回时是否优化了复制。)
但是,这可能看起来更好一些(并且速度会慢得多):
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
string getfile(const string& filename) {
ifstream in(filename.c_str(), ios_base::binary);
in.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit);
return string(istreambuf_iterator<char>(in), istreambuf_iterator<char>());
}
int main(int argc, char* argv[]) {
if (argc != 2) {
cerr << "Usage: this_executable file_to_read\n";
return EXIT_FAILURE;
}
cout << getfile(argv[1]).size() << "\n";
}
while(ugly()) encapsulate_more();
- Marco A.