首页 > 解决方案 > 为什么使用 std::ofstream 进行二进制写入时,std::string.c_str() 不等于 const char*?

问题描述

我想写入文件二进制数据。为此,我使用std::ofstreamwith flagstd::ios::binary和 method write()。好的,如果写我通过了const char*,但是如果我通过了,问题就开始了std::string.c_str()。如果在我的二进制数据中找到空字符 ( '\0'),则此后的所有数据都将具有随机值。我不明白这是怎么回事。我认为,那const char*std::string.c_str()相等的——在这两种情况下,它都是字符数组。但在这个例子中它不是真的吗?为什么write()std::ofstream处理std::string.c_str()另一个const char*?我可以写二进制数据使用std::string吗?

我尝试 memcpystd::string.c_str()到新的字符数组,但没有帮助。

这是我的代码:

int main(int argc, char** argv) {
  try {
    std::ofstream stream1(std::string(argv[1]), std::ios::binary | std::ios::out);
    if (!stream1.is_open())
      throw(std::string("ERROR"));

    const char* str1 = "\x61\x40\x62\x63\x64\x07\x07\x00\xFF\x01\x02\x58\x59\x5A"; //14 data bytes
    std::string str2 = std::string(str1);

    char* str3 = new char[14];
    memcpy(str3, str2.c_str(), 14);
    const char* str4 = const_cast<const char*>(str3);

    stream1.write(str1, 14);
    stream1.write("\n", 1);
    stream1.write(str2.c_str(), 14);
    stream1.write("\n", 1);
    stream1.write(str4, 14);

    delete str3;
  } catch(std::string& error) {
    std::cout << error << std::endl;
  }

  return EXIT_SUCCESS;
}

我从 Vim 得到的: 文本

案例 1 是正确使用const char*的。情况 2 和 3 相等:\x00所有数据都变成随机的。

如果\x00它是行尾,为什么它适用于std::string.c_str(),但不适用于const char*

标签: c++stringbinaryofstream

解决方案


问题出在这一行:

std::string str2 = std::string(str1);

副本将在\x00字符串中停止,因为根据定义,这是字符串文字的结尾。你的str2将只有 7 个字符。即使有过去的字符,它们也不会被复制。当您尝试从不存在的字符串中复制字符时,您最终会得到内存中已经存在的任何垃圾。事实上,这将是未定义的行为。


推荐阅读