【问题标题】:Reading std::string from binary file从二进制文件中读取 std::string
【发布时间】:2009-08-11 20:26:21
【问题描述】:

我之前创建了几个函数,用于读取和写入 std::strings 到以二进制模式打开以读取的 FILE*。他们以前工作得很好(并且 WriteString() 仍然有效),但 ReadString() 在运行时不断给我内存损坏错误。字符串的存储方式是将其大小写为 unsigned int,然后将字符串数据写为 char。

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;

}

任何人都可以看到此代码有任何问题或有任何替代建议吗?

【问题讨论】:

    标签: c++


    【解决方案1】:

    我遇到的最大问题:

    // 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);
    

    这会将文本创建为指向单个字符的指针,然后您尝试将任意数量的字符(可能不止一个)读入其中。为了使其正常工作,您必须在确定大小后将文本创建为 array 个字符,如下所示:

    // 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++ 中使用 C 文件 I/O 是否有充分的理由?使用 C++ 风格的 iostream 可以缓解所有这些问题,并使您的代码更短、更易读。

    【讨论】:

    • 感谢您的回答。我使用 C 文件 IO 的原因仅仅是因为我最初是在我对 C++ 很陌生的时候编写这些函数的,而且我不太了解所有 iostream 的东西。我仍在使用这些函数,只是因为一些使用它们的旧代码(无论如何我打算很快替换)。
    【解决方案2】:

    问题是:

    char* text = new char;
    

    您正在分配一个字符。在您知道size 之后进行分配,并分配您需要的所有size 字符(例如使用new char[size])。 (为避免泄漏,当然,在复制后删除它)。

    【讨论】:

      【解决方案3】:

      很抱歉,我选择的答案对我不起作用。

      // 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);
      

      大小最终是一个非常大的数字。我错过了什么吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 2018-08-24
        • 2015-07-27
        • 1970-01-01
        相关资源
        最近更新 更多