【问题标题】:C++ UTF-8 Swedish Characters are Read as ASCIIC++ UTF-8 瑞典语字符被读取为 ASCII
【发布时间】:2018-06-14 18:22:46
【问题描述】:

有一个 C++ 程序,我需要添加读取文件的功能。 我发现它不适用于欧洲特殊字符。我正在使用的示例是瑞典语字符。

我将代码更改为使用宽字符,但这似乎没有帮助。

我正在阅读的示例文本文件具有以下内容:

"NEW-DATA"="Nysted Vi prøver lige igen"

这是在 Windows 上,Nodepad 说这个文件使用 UTF-8 编码。

在 Visual Studio 中,调试时,读取的字符串显示为 ASCII 格式:

"NEW-DATA"="Nysted Vi prøver lige igen"

我更改了代码以使用“宽”方法:

    std::wifstream infile;
    infile.open(argv[3], std::wifstream::in);
    if (infile.is_open())
    {
        std::wstring line;
        while (std::getline(infile, line))
        {

....

我还需要做些什么来让它正确识别 UTF-8?

【问题讨论】:

  • 离题,但这不是瑞典语,而是丹麦语。瑞典语不使用“ø”。
  • BTW - 该文件有一个 BOM(显示为“”)。 BOM 是不属于文件文本内容的元数据。因此,不应允许它以line 结尾。请参阅此BOM test and putback example。 (BOM 可能是记事本曾经提出 UTF-8 作为编码的猜测的一部分。如果您不喜欢猜测,请询问发件人使用了哪种编码。同意 UTF- 可能是个好主意8,因此您每次打开来自同一来源的任何文本文件的任何版本时都可以依赖它。)

标签: c++ utf-8


【解决方案1】:

您可以将 UTF-8 内容读取为 ASCII 文本,但必须将它们转换为宽字符以允许 Visual Studio 将其解释为 unicode。

这是我们使用的一个股票函数:

BSTR UTF8ToBSTR(char const* astr)
{
   static wchar_t wstr[BUFSIZ];

   // Look for the funtion description in MSDN.
   // Use of CP_UTF8 indicates that the input is UTF8 string.

   // Get the size of the output needed for the conversion.
   int size = MultiByteToWideChar(CP_UTF8, 0, astr, -1, NULL, 0);

   // Do the conversion and get the output.
   MultiByteToWideChar(CP_UTF8, 0, astr, -1, wstr, size);

   // Allocate memory for the BSTR and return the BSTR.
   return SysAllocString(wstr);
}

您必须添加代码以释放调用 SysAllocString(wstr) 分配的内存。

例如

BSTR bstr = UTF8ToBSTR(...);

// Use bstr
// ...


// Deallocate memory
SysFreeString(bstr);

【讨论】:

  • 是否有在 Windows 和 Linux 上处理 UTF-8 的可移植方法?我希望能够使用 wchar_t。我认为 BSTR 是 Microsoft 特有的。
  • 我们说这只是 Visual Studio 的限制,对吧?仅仅为了调试器窗口而对程序进行所有这些更改真的值得吗?内存中的实际数据应该没问题。
  • @GeorgeHernando: BSTR 实际上是 wchar_t* 的类型别名
  • @GeorgeHernando "有在 Windows 和 Linux 上处理 UTF-8 的可移植方法吗?" - 看看std::wstring_convert
  • @GeorgeHernando 如果你想要的是跨平台代码在 UTF-8 和 wchar_t 之间进行转换,你可以在 stackoverflow.com/a/148766/5987 查看我的代码。
【解决方案2】:

发生的情况是您有一个 UTF-8 编码的文件,但您试图读取它,就好像它由宽字符组成一样。那是行不通的。如您所见,BOF 标记已被逐字读取到您的字符串中,因此很明显,您使用的机制不包含任何尝试对字符进行任何类型的解析和解码 UTF-8 字节对的逻辑。

宽字符和 UTF-8 是两个根本不同的东西。 你不可能仅仅通过阅读 UTF-8 加入wchar_t(或std::wstring)并阅读它。你是 需要使用某种 unicode 库。有 std::wstring_convert 在 C++11 中(但这需要工具支持)和 有手册mbstowcs()/wcstombs() 路线。无处不在 最好使用图书馆。

来源: https://www.reddit.com/r/cpp/comments/108o7g/reading_utf8_encoded_text_files_to_stdwstring/

我认为mbstowcs()/wcstombs() 是微软MultiByteToWideChar()MultiByteToWideChar() 的便携式替代品。

【讨论】:

  • 您可以将imbue() UTF-8 语言环境设置为std::wifstream,然后它可以读取UTF-8 文件并将它们转换为编译器用于wchar_t 的任何编码(Windows 上的UTF-16 , UTF-32 在其他平台上)。
猜你喜欢
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2015-01-17
  • 1970-01-01
  • 2011-06-19
相关资源
最近更新 更多