1. ホーム
  2. c++

[解決済み] ASCII ファイルを丸ごと C++ std::string に読み込む [重複] 。

2022-03-15 15:02:14

質問

ファイルを丸ごとメモリに読み込んで、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()

何かアイデアはありますか?

解決方法は?

更新してください。 この方法は、STLのイディオムにはよく従っているものの、実際には驚くほど非効率的であることが判明しました 大きなファイルでは使わないでください。(参照 http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html )

ファイルからstreambufのイテレータを作り、それで文字列を初期化すればいいのです。

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());

をどこで取得しているのかは不明です。 t.open("file.txt", "r") の構文からです。私の知る限り、それはメソッドではなく std::ifstream が持っています。C言語の fopen .

編集する また、文字列コンストラクタの最初の引数の周りにある余分な括弧に注意してください。 これらは必須です . これは、「"」と呼ばれる問題を防ぐためです。 最も厄介なパース この場合、通常のようなコンパイルエラーにはなりませんが、興味深い(間違った)結果を得ることになります。

コメント中のKeithBの指摘に従い、(文字列クラスの自動再割り当てに頼らず)前もってすべてのメモリを確保する方法を紹介します。

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str;

t.seekg(0, std::ios::end);   
str.reserve(t.tellg());
t.seekg(0, std::ios::beg);

str.assign((std::istreambuf_iterator<char>(t)),
            std::istreambuf_iterator<char>());