簡體   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