C++不使用string/vector时如何正确写入char数组到文本文件并解决乱码
核心问题排查
- 返回栈内存指针:你定义的
to_return是test()函数内的局部栈数组,函数执行结束后栈空间会自动回收,返回的指针直接变成野指针,访问这段内存的结果是未定义的,大概率出现乱码或者程序崩溃。此处std::move对原生指针完全无作用,属于多余写法。 - 缺少字符串结束符:你构造的字符数组末尾没有加
'\0',调用strlen(to_write)的时候会持续向后读取内存直到遇到0值,计算出的长度完全不符合预期。 - 文件写入逻辑错误:你把
size_t类型的len的二进制值直接写入了文件开头,这部分二进制内容在文本编辑器中打开就是乱码,且反复开闭文件属于多余操作。 - 多字节字符截断问题:
♥是多字节Unicode字符,直接赋值给单字节char会被截断,导致字符显示异常。
修复代码
1. 修复A::test()方法
因你无法使用std::string和std::vector,需手动在堆上申请内存返回,记得调用方用完要free释放避免内存泄漏:
char* A::test() { // 计算缓冲区长度:some_value * 3 + 1(末尾结束符占位) int buf_len = 3 * this->some_value + 1; char* to_return = (char*)malloc(buf_len); // 可根据需求添加内存申请失败的兜底逻辑 for (int i = 0; i < this->some_value; i++) { // 注意♥是多字节字符:UTF-8编码下占3字节,GBK编码下占2字节,直接赋值给char会截断 // 如果是UTF-8环境,可替换为对应字节赋值: // to_return[3*i] = 0xE2; to_return[3*i+1] = 0x99; to_return[3*i+2] = 0xA5; // 下方b和空格的偏移量需对应调整 to_return[3*i] = '♥'; to_return[3*i+1] = 'b'; to_return[3*i+2] = ' '; } // 补充字符串结束符 to_return[buf_len - 1] = '\0'; return to_return; }
2. 修复文件写入逻辑
ofstream file; // 仅需打开一次,trunc模式会直接清空原有内容 file.open("myfile.txt", ofstream::out | ofstream::trunc); char* to_write = a_obj->test(); size_t len = strlen(to_write); // 不需要将len的二进制写入文件,直接写入文本内容即可,如需存储长度可单独存放 file.write(to_write, len); file.close(); // 手动释放test中malloc申请的内存,避免内存泄漏 free(to_write);
额外注意事项
如果你的开发环境不允许使用堆内存,可以改成由调用方提前分配足够大的缓冲区,传入test()方法填充内容,从根源避免栈内存返回的问题。
内容的提问来源于stack exchange,提问作者Piotr Wasilewicz
相关产品推荐
相关产品推荐

