【问题标题】:Why ofstream does not write utf16 on linux in binary mode?为什么ofstream不以二进制模式在linux上写utf16?
【发布时间】:2014-10-01 20:33:51
【问题描述】:

在 Linux 上,我在使用 ofstream 类将 UTF-16 写入文件时遇到了一些麻烦,而相同的代码在 Windows 上运行良好。下面是示例代码

MyString content;
content = L"hello\r\n";
const short unsigned int* output = content.asUnicodeType<MyString::UTF16>().c_str();
ofstream outFile("test.txt", std::ios::out | std::ios::binary);
outFile.write((char *)output, content.size() * sizeof(MyString::UTF16));
//outFile.write((char *)content.c_str(), content.size() * sizeof(wchar_t));
outFile.close();
return 0;

我已确认输出已正确转换为 UTF-16 格式

(gdb) x /16b output
0x61a288:       104     0       101     0       108     0       108     0
0x61a290:       111     0       13      0       10      0       0       0

但是,完成后,我尝试打开文件。尽管我要求它以二进制模式写入,但看起来内容被写入为 UTF8

如果我切换并写为宽字符,那么内容在Linux上写为UTF32是正确的。

任何建议都会很棒!

PS:由于平台限制,我不能使用C++ 11标准

谢谢

【问题讨论】:

  • 它只是一个包裹 wchar_t 字符串的类。这并不重要,因为我正在编写输出的内容
  • od -t x1 test.txt 带给你什么?
  • 感谢您提醒我这一点。我在 Windows 上打开文件,因为我错过了 BOM,它读取内容为 ansi.. 添加 BOM.. 现在一切都很好。

标签: c++ linux utf-16 ofstream c++03


【解决方案1】:

这实际上是把内容写成UTF-16但是因为我错过了BOM,在Windows上打开的文件没有识别它所以我以为它把内容写成UTF8

【讨论】:

    【解决方案2】:

    如果content.asUnicodeType&lt;MyString::UTF16&gt;() 返回std::string,那么您的行为未定义。 .c_str() 返回由 std::string 拥有的 c 字符串,但在您的情况下,std::string 是一个临时对象,这会导致其 c 字符串被立即删除。

    要解决此问题,只要您需要 c 字符串,就必须保留 std::string

    auto output_s = content.asUnicodeType<MyString::UTF16>();
    const short unsigned int* output = output_s.c_str();
    

    我不知道这是否会解决您的问题,但无论如何解决未定义的行为是个好主意。

    哦,顺便说一句,尝试在任何地方使用 utf8,尤其是在读写文件时。无论您花费多少精力来使 utf16 正确,您都可能做错了。 见http://utf8everywhere.org

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 2015-08-28
      • 1970-01-01
      相关资源
      最近更新 更多