【问题标题】:How do I write a UTF-8 encoded string to a file in windows, in C++如何在 C++ 中将 UTF-8 编码字符串写入 Windows 中的文件
【发布时间】:2011-04-27 18:41:16
【问题描述】:

我有一个字符串,其中可能包含或不包含 unicode 字符,我正在尝试将其写入 Windows 上的文件。下面我发布了一段代码示例,我的问题是当我打开并从窗口读取值时,它们都被解释为 UTF-16 字符。

char* x = "Fool";
FILE* outFile = fopen( "Serialize.pef", "w+,ccs=UTF-8");
fwrite(x,strlen(x),1,outFile);
fclose(outFile);

char buffer[12];
buffer[11]=NULL;
outFile = fopen( "Serialize.pef", "r,ccs=UTF-8");
fread(buffer,1,12,outFile);
fclose(outFile);

如果我在写字板等中打开文件,这些字符也会被解释为 UTF-16。我做错了什么?

【问题讨论】:

    标签: c++ windows unicode file-io utf-8


    【解决方案1】:

    是的,当您指定文本文件应以 UTF-8 编码时,CRT 会隐式假定您将 Unicode 文本写入文件。不这样做没有意义,你不需要UTF-8。这将正常工作:

    wchar_t* x = L"Fool";
    FILE* outFile = fopen( "Serialize.txt", "w+,ccs=UTF-8");
    fwrite(x, wcslen(x) * sizeof(wchar_t), 1, outFile);
    fclose(outFile);
    

    或者:

    char* x = "Fool";
    FILE* outFile = fopen( "Serialize.txt", "w+,ccs=UTF-8");
    fwprintf(outFile, L"%hs", x);
    fclose(outFile);
    

    【讨论】:

    • 当然,您会将 Unicode 文本写入文件,但关键是 CRT 假定您将写入 UTF-16
    • @dan - 不,它假定您将编写 wchar_t。在 Windows 上它是 utf-16 是一个实现细节。
    【解决方案2】:

    如果您使用C++11 标准,这很容易(因为有很多额外的包含,例如"utf8",可以永远解决这个问题)。

    但是如果你想使用旧标准的多平台代码,你可以使用这种方法来编写流:

    1. Read the article about UTF converter for streams
    2. 从以上来源将stxutif.h 添加到您的项目中
    3. 以 ANSI 模式打开文件并将 BOM 添加到文件的开头,如下所示:

      std::ofstream fs;
      fs.open(filepath, std::ios::out|std::ios::binary);
      
      unsigned char smarker[3];
      smarker[0] = 0xEF;
      smarker[1] = 0xBB;
      smarker[2] = 0xBF;
      
      fs << smarker;
      fs.close();
      
    4. 然后以UTF 的身份打开文件并在其中写入您的内容:

      std::wofstream fs;
      fs.open(filepath, std::ios::out|std::ios::app);
      
      std::locale utf8_locale(std::locale(), new utf8cvt<false>);
      fs.imbue(utf8_locale); 
      
      fs << .. // Write anything you want...
      

    【讨论】:

    • 用 C++11 是怎么做到的?
    • 为什么需要 bom?我读到它在 utf-8 中不是必需的,甚至是不推荐的,因为它没有任何意义。是在windows中写bom还是可以完全避免?
    猜你喜欢
    • 2016-01-11
    • 2012-06-10
    • 2023-03-27
    • 2013-01-31
    • 2011-06-16
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 2016-05-20
    相关资源
    最近更新 更多