2010-12-04 22 views
1

私は、ファイルの内容を取得するために設計された機能があります。C++文字列割り当てエラー

bool getFileContents(std::string loc, std::string &code) { 
    std::ifstream file(loc.c_str()); 

    if(!file.is_open()) 
     return err("Source file could not be read"); 

    int length; 
    file.seekg(0, std::ios::end); 
    length = file.tellg(); 
    file.seekg(0, std::ios::beg); 

    char *buffer = new char[length]; 
    file.read(buffer, length); 
    code = buffer; 
    delete[] buffer; 

    file.close(); 

    return true; 
} 

を、私はこの機能を実行すると、ファイルの長さが常に正確に取得されます。しかし、関数をファイルで1回呼び出すと、存在しないファイルでもう一度呼び出すと、もう一度元のファイルで呼び出すと、文字列 'バッファ'はint '長さ'より大きくなります。

文字列 'code'に文字列 'code'がコピーされた場合、 'code'は 'length'よりも長くなります。 'code'はそれぞれのインスタンスで 'getFileContents'の呼び出しの直前でインスタンス化されるため、以前の値の問題ではありません。

これは、ファイルの内容を取得した後、ファイルからテキストを追加または削除し、同じファイルの内容を再度取得する場合にも発生します。

私は文字列に関する経験がほとんどなく、正しく使用していないことを示していますが、私が使用しているコードは例であり、私の人生にとって間違ったものは見つけられません。任意の助け

おかげで、 ワイアット

+0

例外についてよく知っていませんか?エラーを報告する関数を呼び出すことでエラーを処理しているように見えますが、常にfalseを返します。したがって、例外を伝播するために戻り値を使用でき、呼び出し元にoutパラメータを作成させることができます。これは信じられないほど後ろ向きです。 'return'で値を返します。例外を使用して、例外的なイベント(想定されているときに存在しないファイルなど)を報告します。 –

+0

例外はどのようなメリットをもたらしますか?私は他の誰のためにもこのコードを作っているわけではないし、グローバルなエラー文字列を持つことは私の仕事の妨げにはならない。私はむしろこのメソッドを好み、エラー処理を集中させ、try/catchブロックよりもはるかに簡潔です。 – wyatt

+0

'code'変数を使用してファイルの読み込みから内容をコピーすることはできませんでした(結局、参照によってパラメータを渡しています)。 – stanigator

答えて

3

さて、問題はcode = bufferはバッファが終了する場所を知ってNUL(\ 0)文字に依存しているということです。あなたは偶然に(時にはプログラムが始まったばかり)、NUL文字を得ることができますが、必ずしもそうではありません。したがって断続的な行動。

code = buffercode = std::string(buffer, length)に置き換えてください。 AIXによって記述\ 0問題のほかに

+0

不要な割り当てを避けるには、 'code.assign(buffer、buffer + length)'を使用する方が良いでしょう。 – grep

+0

** Doc Brown **、ファイルに\ 0が含まれているとどうなりますか? – grep

0

、あなたはここで危険な(それがdelete前に例外かもしれない、とあなたはメモリリークがあるでしょう)必要はありませんダブル割り当てを、行います。

code.resize(length); 
file.read(&code[0], length); 

をそしてreadの戻り値をチェックすることを忘れないでください:代わりに、次のように、文字列内のバッファを割り当てることができます。すべてのlengthバイトが1ステップで読み取られるという保証はありません。

関連する問題