c++ - 为什么使用 std::ofstream 进行二进制写入时,std::string.c_str() 不等于 const char*?
问题描述
我想写入文件二进制数据。为此,我使用std::ofstream
with 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*
?
解决方案
问题出在这一行:
std::string str2 = std::string(str1);
副本将在\x00
字符串中停止,因为根据定义,这是字符串文字的结尾。你的str2
将只有 7 个字符。即使有过去的字符,它们也不会被复制。当您尝试从不存在的字符串中复制字符时,您最终会得到内存中已经存在的任何垃圾。事实上,这将是未定义的行为。
推荐阅读
- python - 我尝试使用功能 API 在 tensorflow 2.x 中创建模型,但出现 LSTM 层不兼容错误
- python - Heroku 在我的不和谐机器人中找不到 PyNaCl
- r - 将数据强制转换为矩阵以进行网络分析 R
- javascript - 如何处理`Type | 打字稿和错误检查/测试中的布尔值返回值
- python - 线性回归中 r2_score 和 score() 的区别
- android - 如何使用 intellij idea 配置我的智能手机
- sql - 获取锁定的存储过程返回的行数,而不使用 @@rowcount
- continuous-integration - VirtualBox 执行器因“准备环境:进程以状态 1 退出”而失败
- c - 为什么编译器在读取文本文件时会分配多余的内存?
- firebase - 在 ListView 中从 Firebase 获取数据时出现重复