繁体   English   中英

如何读取文件并将其写入字符串 c++

[英]How to read a file and write it on a string c++

我找到了一个解决方案,但我相信有更好的方法来做到这一点。 如何在不使用复杂工具的情况下改进我的代码?

string Read(string& file) {
    ifstream in;
    string text;
    string s;
    in.open(file, ios::in);
    try {
        while (!in.eof()) {
            text.append(s);
            in >> s;
        }
    }
    catch (exception& ex) {
        cout << ex.what();
    }
    in.close();
    return text; 
}

您的代码读取空格分隔的单词,丢弃空格,并将所有单词连接成一个没有空格的字符串。 您可能希望逐字阅读文件内容。


在没有循环的情况下将整个文件读入std::string的一种方法是使用带有两个迭代器的std::string构造函数 - 构造函数为您执行循环。 使用std::istreambuf_iterator调用它:

#include <string>
#include <fstream>
#include <iterator>
#include <stdexcept>

std::string read(std::string filename) {
    std::ifstream file(filename, std::ios_base::binary | std::ios_base::in);
    if(!file.is_open())
        throw std::runtime_error("Failed to open " + filename);
    using Iterator = std::istreambuf_iterator<char>;
    std::string content(Iterator{file}, Iterator{});
    if(!file)
        throw std::runtime_error("Failed to read " + filename);
    return content;
}

另一种选择是将文件映射到内存中(零复制方法),例如使用boost::iostreams::mapped_file ,这是前所未有的干净和高效。 对于大于〜100kB的文件,该方法更快,获得硬数字的基准。

一种优化是立即填充文件映射的所有页面,而不是在首次访问时按需分页

例子:

#include <iostream>
#include <boost/iostreams/device/mapped_file.hpp>

int main() {
    using boost::iostreams::mapped_file;
    mapped_file content("/etc/lsb-release", mapped_file::readonly);
    std::cout.write(content.const_data(), content.size());
}

最简单的方法(通常意味着最好的方法)是一次读取一个字符的文件

string text;
char ch;
while (file.get(ch)) {
    text += ch;
}

循环

while (!in.eof()) {
    text.append(s);
    in >> s;
}

是错误的,因为条件while (!in.eof())可能为false ,即使in >> s的前一个语句成功。 最好写while (!in.fail())而不是while (!in.eof())

但是,像这样编写循环会更清晰,效率更高:

while ( in >> s ) {
    text.append(s);
}

此循环条件间接使用in.operator bool() ,相当于!in.fail()

这个循环比另一个循环更高效的原因是在另一个循环的第一次迭代中,总是附加一个空字符串。 在此循环中不再是这种情况。

尽管您没有在问题中说明这一点,但在问题的评论部分中,您表示最好保留空白字符而不是丢弃。 在这种情况下,您不应该使用operator >>来读取输入,它一次读取一个单词,但您应该使用std::getline ,它一次读取一行:

string Read(string& file) {
    ifstream in;
    string text;
    string s;
    in.open(file, ios::in);
    while ( getline( in, s ) ) {
        text.append( s );
        text.append( "\n" );
    }
    return text; 
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM