c++ - 将整个 ASCII 文件读入 C++ std::string

标签 c++ string caching file-io standard-library

我需要将整个文件读入内存并将其放入 C++ std::string

如果我把它读成char[],答案很简单:

std::ifstream t;
int length;
t.open("file.txt");      // open input file
t.seekg(0, std::ios::end);    // go to the end
length = t.tellg();           // report location (this is the length)
t.seekg(0, std::ios::beg);    // go back to the beginning
buffer = new char[length];    // allocate memory for a buffer of appropriate dimension
t.read(buffer, length);       // read the whole file into the buffer
t.close();                    // close file handle

// ... Do stuff with buffer here ...

现在,我想做完全相同的事情,但使用 std::string 而不是 char[]。我想避免循环,即我不想想要:

std::ifstream t;
t.open("file.txt");
std::string buffer;
std::string line;
while(t){
std::getline(t, line);
// ... Append line to buffer and go on
}
t.close()

有什么想法吗?

最佳答案

有几种可能性。我喜欢使用字符串流作为中间人:

std::ifstream t("file.txt");
std::stringstream buffer;
buffer << t.rdbuf();

现在“file.txt”的内容以字符串形式提供为 buffer.str()

另一种可能性(虽然我当然也不喜欢它)更像你原来的:

std::ifstream t("file.txt");
t.seekg(0, std::ios::end);
size_t size = t.tellg();
std::string buffer(size, ' ');
t.seekg(0);
t.read(&buffer[0], size); 

正式地,这在 C++98 或 03 标准下不需要工作(字符串不需要连续存储数据),但实际上它适用于所有已知的实现,C++11 及更高版本可以需要连续存储,因此可以保证与它们​​一起使用。

至于为什么我也不喜欢后者:首先,因为它更长且更难阅读。其次,因为它要求您使用您不关心的数据初始化字符串的内容,然后立即覆盖该数据(是的,与读取相比,初始化时间通常微不足道,所以这可能无关紧要,但对我来说仍然感觉有点不对)。第三,在文本文件中,文件中的位置 X 并不一定意味着您已经阅读了 X 个字符才能到达该位置——它不需要考虑诸如行尾翻译之类的事情。在进行此类翻译的真实系统(例如,Windows)上,翻译后的形式比文件中的短(即,文件中的“\r\n”在翻译后的字符串中变成“\n”)所以你所做的一切保留了一点你从不使用的额外空间。再说一次,并没有真正引起大问题,但总感觉有点不对劲。

关于c++ - 将整个 ASCII 文件读入 C++ std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2602013/

相关文章:

c++ - 调用临时对象的方法安全吗?

c++ - 通过 unsigned char 别名访问对象,加载和存储时会发生什么?

java - 在 Android 中从文件读取/写入字符串

mysql - 在 MySQL 中使用单引号存储值

php - 为什么即使在发送无缓存 header 后页面仍在缓存?

c++ - 如果不包含<string.h>,为什么我的程序可以成功编译?

c++ - 矩阵的平均四分之一

string - Bash:从字符串中提取(百分比)可变长度数

javascript - 在我的本地机器上引用 javascript 文件

java - 处理 JPA 缓存