为什么用std::ofstream写二进制,std::string.c_str()不等于const char*?
Why when use std::ofstream for binary writing, std::string.c_str() not equal const char*?
我想写入文件二进制数据。为此,我将 std::ofstream
与标记 std::ios::binary
和方法 write()
一起使用。好的,如果我通过 const char*
进行写入,但如果我通过 std::string.c_str()
,问题就开始了。如果在我的二进制数据中找到空字符 ('[=19=]'
),则此后的所有数据都将具有随机值。我不明白这是怎么回事。我认为 const char*
和 std::string.c_str()
是相等的——在这两种情况下它都是 char 数组。但在这个例子中不是真的吗?为什么 write()
在 std::ofstream
中处理 std::string.c_str()
另一个 const char*
?我可以使用 std::string
写入二进制数据吗?
我试过 memcpy std::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*
?
问题出在这一行:
std::string str2 = std::string(str1);
复制将在字符串中的 \x00
处停止,因为根据定义这是字符串文字的结尾。您的 str2
将只有 7 个字符。即使有字符过去,也不会被复制。当您尝试从不存在的字符串中复制字符时,您最终会得到内存中已经存在的任何垃圾。事实上,这将是未定义的行为。
我想写入文件二进制数据。为此,我将 std::ofstream
与标记 std::ios::binary
和方法 write()
一起使用。好的,如果我通过 const char*
进行写入,但如果我通过 std::string.c_str()
,问题就开始了。如果在我的二进制数据中找到空字符 ('[=19=]'
),则此后的所有数据都将具有随机值。我不明白这是怎么回事。我认为 const char*
和 std::string.c_str()
是相等的——在这两种情况下它都是 char 数组。但在这个例子中不是真的吗?为什么 write()
在 std::ofstream
中处理 std::string.c_str()
另一个 const char*
?我可以使用 std::string
写入二进制数据吗?
我试过 memcpy std::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*
?
问题出在这一行:
std::string str2 = std::string(str1);
复制将在字符串中的 \x00
处停止,因为根据定义这是字符串文字的结尾。您的 str2
将只有 7 个字符。即使有字符过去,也不会被复制。当您尝试从不存在的字符串中复制字符时,您最终会得到内存中已经存在的任何垃圾。事实上,这将是未定义的行为。