2009-08-11 28 views
1

バイナリモードで読み込むために開かれたFILE *にstd :: stringsを読み書きするために私は少し前に作成した関数をいくつか持っています。以前はうまくいきましたが(そしてWriteString()はまだ動作しますが)、ReadString()は実行時にメモリ破損エラーを返し続けます。文字列は、char型の文字列データの前に符号なし整数としてサイズを書き込むことによって格納されます。バイナリファイルからstd :: stringを読み込みます

bool WriteString(std::string t_str, FILE* t_fp) { 
// Does the file stream exist and is it valid? If not, return false. 
if (t_fp == NULL) return false; 
// Create char pointer from string. 
char* text = const_cast<char*>(t_str.c_str()); 
// Find the length of the string. 
unsigned int size = t_str.size(); 
// Write the string's size to the file. 
fwrite(&size, sizeof(unsigned int), 1, t_fp); 
// Followed by the string itself. 
fwrite(text, 1, size, t_fp); 
// Everything worked, so return true. 
return true; 

} 



std::string ReadString(FILE* t_fp) { 
// Does the file stream exist and is it valid? If not, return false. 
if (t_fp == NULL) return false; 
// Create new string object to store the retrieved text and to return to the calling function. 
std::string str; 
// Create a char pointer for temporary storage. 
char* text = new char; 
// UInt for storing the string's size. 
unsigned int size; 
// Read the size of the string from the file and store it in size. 
fread(&size, sizeof(unsigned int), 1, t_fp); 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 
// Store the contents of text in str. 
str = text; 
// Resize str to match the size else we get extra cruft (line endings methinks). 
str.resize(size); 
// Finally, return the string to the calling function. 
return str; 

} 

このコードで問題が発生した場合、または代替提案がありますか?

答えて

5

最大の主要な問題:

// Create a char pointer for temporary storage. 
char* text = new char; 
// ... 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 

これは単一文字へのポインタとして、テキストを作成し、あなたは1よりも潜在的に多くの多くの文字の任意の数を(読みしてみてください)を入力します。

// UInt for storing the string's size. 
unsigned int size; 
// Read the size of the string from the file and store it in size. 
fread(&size, sizeof(unsigned int), 1, t_fp); 
// Create a char pointer for temporary storage. 
char* text = new char[size]; 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 

第二に、あなたはそのメモリを解放しません:あなたはサイズがこのように、何であったか考え出した後、これが正しく動作するためには、あなたは、文字の配列としてテキストを作成する必要がありますあなたはテキストに割り当てられました。

// Free the temporary storage 
delete[] text; 

最後に、CファイルI/OをC++で使用する理由はありますか? C++スタイルのiostreamを使用すると、これがすべて軽減され、コードがずっと短く読みやすくなりました。

+0

お返事ありがとうございます。私がCファイルIOを使用している理由は、単に私がC++を初めて使ったときに元々これらの関数を書いたので、すべてのiostreamの内容を理解できなかったからです。私はまだそれらを使用するいくつかの古いコードのために(私はとにかくすぐに置き換えるつもりである)これらの関数を使用しています。 –

2

問題がある:あなたが単一の文字を割り当てている

char* text = new char; 

sizeを知った上で割り当てを行い、必要な文字(new char[size]など)をすべてsizeに割り当てます。 (漏れを避けるために、後でコピーしてください私に飛び出し

0

申し訳ありませんが、選択された回答は私のためには機能しません。

// UInt for storing the string's size. 
unsigned int size; 
// Read the size of the string from the file and store it in size. 
fread(&size, sizeof(unsigned int), 1, t_fp); 
// Create a char pointer for temporary storage. 
char* text = new char[size]; 
// Read [size] number of characters from the string and store them in text. 
fread(text, 1, size, t_fp); 

サイズが非常に大きくなります。何か不足していますか?

関連する問題