2016-06-20 12 views
0

符号なし文字のファイルをベクトルに読み込もうとしています。これを行うには、入力ファイルストリームを作成し、そのデータを文字列ストリームに読み込み、文字列ストリームの内容を使用してベクトルを初期化します。これを行うもっと良い方法がおそらくあります。既存のコードでは、特定のファイルを使用してセグメンテーション違反が発生します。イテレータでベクトルを初期化するC++

string file_name = "output/comp" + to_string(start_id) + ".xml"; 

if(!file_exists(file_name)) 
{ 
    cout << "File could not be found." << endl; 
    return 0; 
} 

ifstream ifs(file_name); 
stringstream ss; 
ss << ifs.rdbuf(); 
ss >> noskipws; 

vector<unsigned char> raw_data(ss.str().begin(), ss.str().end()); 

私はすべての必要なヘッダとusing宣言を含んでおり、file_exists()ファイルが存在するかどうかを示すブール値を返します。

私の質問は次のとおりです:上記のコードが間違っているのはなぜですか?同じ目標を正しく達成するための最良の方法は何ですか?

+0

ようistream_iterator Sを用いてベクターに直接ファイルを読み込むことができますおそらく、ファイルオープンモードに 'binary'を追加する必要があります –

答えて

8

std::stringstream::str()std::string返し終わりにバイトを望んでいた忘れてしまいました。つまり、一時的な文字列です。

のでss.str().begin()は、一時的な文字列の開始イテレータを返し、両方ss.str()呼び出しが異なる一時的な文字列を返すされているのでss.str().end()は、異なる一時的な文字列の終了イテレータを返します。異なるオブジェクト間でイテレータを混在させることはできません!

std::string str = ss.str(); 

そして今はちょうどstr.begin()str.end()を渡す:

は、この問題を解決する1つの文字列を使用します。

0

私はおそらく、文字列ストリームで何か理由がセグメンテーションフォルトを引き起こす正確にわからないんだけど、C++ 11で、それはあなたが任意のIStreamの誘導体を持っていたら、文字列にファイルを読み込むことは非常に簡単です:

std::string readFileAsString(std::istream& stream) 
{ 
    return std::string(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>()); 
} 

編集申し訳ありませんが、私はあなたが

return std::vector<char>(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>()); 
2

vector<unsigned char> raw_data(ss.str().begin(), ss.str().end()); 

の問題はstr()は一時的な文字列を返すことです。つまり、beginに使用するstringは、endに同じstringを使用していません。イテレータは同じstringを参照していないので、それらを一緒に使用することはできません。

代わりのstrignstreamを使用して、我々は

std::ifstream ifs(file_name); 
std::istream_iterator<unsigned char> start(ifs), end; 
std::vector<unsigned char> raw_data(start, end); 
関連する問題