【问题标题】:Input encoding issue in Windows C++Windows C++ 中的输入编码问题
【发布时间】:2016-05-06 18:15:52
【问题描述】:

我正在使用 Visual Studio 2013 开发一个简单的 console 应用程序

int _tmain(int argc, _TCHAR* argv[])
{    
    std::wstring name;
    std::wcout << L"Enter your name: ";
    std::wcin >> name;
    std::wcout << L"Hello, " << name << std::endl;
    system("pause");
    return 0;
}

如果我输入Ángel,应用程序运行良好,输出为

Hello, Ángel

问题是如果我在上面放一个断点

std::wcout << L"Hello, " << name << std::endl;

Visual Studio 调试器显示

+       name    L"µngel"    std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >

虽然控制台中的输出在程序的其他部分是正确的,但我调用了 win32api 函数 CopyFileW() 并且它总是失败,因为路径有 substring Ángelsubstring 传递给函数被转换为µngel

【问题讨论】:

  • 我认为您需要更改源文件的编码,我认为类似于 utf-16。
  • 问题在于命令提示符使用不同于 Win32 API 的编码。这个问题的答案有帮助吗? stackoverflow.com/questions/15826188/…

标签: c++ windows


【解决方案1】:

问题是默认情况下 Windows 控制台已损坏。

问题是由于 Windows 在控制台应用程序中使用的 8 位代码页与在 Windows 应用程序中不同。默认情况下,在西方 Windows 版本中,默认的 8 位代码页(称为 ANSI)是 Windows-1252,而控制台 8 位代码页(称为 OEM)是 CP850。

由于您的程序不知道它是从控制台读取还是从重定向文件读取,它只是假设 ANSI 输入。但是当你键入Á 时,它实际上是来自CP850 的代码点:0xB5。然后使用Windows-1252 将其解释为µ,即Unicode 字符U+00B5。有趣的是,当您将其打印到控制台时,会发生逆变换,您会再次看到Á。两错成对!

但是当您想在非控制台上下文中使用该字符时,它实际上是一个µ

您可能认为您可以从 OEM 转换为 ANSI,然后从 ANSI 转换为 Unicode,这似乎可行...直到您将程序运行为:

c:\> myprogram < input.txt

你用记事本写了input.txt,所以它使用ANSI,然后你正在做一个你不需要的转换。

然后你说你可以检测你是在读取实际的控制台还是重定向,并且只有在没有重定向时才进行 OEM 到 ANSI 的转换......直到你这样做:

c:\> echo Ángel | myprogram

你又做错了!

有很多替代方案,但没有一个完全可以正常工作。至少您应该使用 Unicode 字体,然后使用更正常的代码页。 chcp 1252 之类的东西可以更改 OEM 代码页以匹配 ANSI 代码页。您甚至可以使用一些注册表 foo 默认配置它:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\OEMCP=1252

【讨论】:

    猜你喜欢
    • 2021-09-07
    • 1970-01-01
    • 2013-12-15
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多