抱歉拖到这里。虽然我认为强调一些问题很重要。据我了解,OS-X 能够将默认 OS 代码页设置为 UTF-8,因此答案主要是关于在后台使用 UTF-16 的 Windows,其默认 ACP 代码页取决于指定的操作系统区域。
首先你可以打开Character Map,找到
äö
两者都位于代码页 1252(西部)中,因此这不是MBCS 问题。可能是 MBCS 问题的唯一方法是使用 MBCS(Shift-JIS、Big5、Korean、GBK)编码保存文件。
使用
setlocale( LC_ALL, "" )的答案
没有深入了解 äö 在命令提示符窗口中错误呈现的原因。
命令提示符确实使用自己的代码页,即 OEM 代码页。这是对以下 (OEM) 代码页及其字符映射的参考。
进入命令提示符并键入以下命令 (Chcp)将显示命令提示符正在使用的当前 OEM 代码页。
通过使用 setlocal(LC_ALL,"") 遵循 Microsoft 文档,它详细说明了以下行为。
设置语言环境(LC_ALL,“”);
将语言环境设置为默认值,即从操作系统获取的用户默认 ANSI 代码页。
您可以手动执行此操作,方法是使用 chcp 并传递您所需的代码页,然后运行您的应用程序,它应该可以完美地输出文本。
如果这是一个多字节字符集问题,那么将会有其他问题的完整列表:
在 MBCS 下,字符被编码为一个或两个字节。在双字节字符中,第一个或“前导字节”表示它和后面的字节都将被解释为一个字符。第一个字节来自保留用作前导字节的一系列代码。哪些字节范围可以是前导字节取决于使用的代码页。例如,日语代码页 932 使用 0x81 到 0x9F 范围作为前导字节,但韩语代码页 949 使用不同的范围。
看看情况,长度是 4 而不是 2。我会说文件格式已保存为 UTF-8(它实际上可以保存为 UTF-16,尽管您会很快遇到问题稍后与编译器一起使用)。您使用的字符不在 0 到 127 的 ASCII 范围内,UTF-8 将 Unicode 代码点编码为两个字节。您的编译器正在打开文件并假定它是您的默认操作系统代码页或 ANSI C。解析字符串时,它会将字符串解释为 ANSI C 字符串 1 字节 = 1 个字符。
为了解决这个问题,在 windows 下将 UTF-8 字符串转换为 UTF-16 并使用 wprintf 打印。目前没有对 Ascii/MBCS stdio 函数的原生 UTF-8 支持。
对于 Mac OS-X,它具有 UTF-8 的默认 OS 代码页,那么我建议遵循 Jonathan Leffler 解决问题的方法,因为它更优雅。虽然如果您稍后将其移植到 Windows,您会发现您需要使用下面的示例将字符串从 UTF-8 转换为 UTF-16。
在任一解决方案中,您仍然需要将命令提示符代码页更改为您的操作系统代码页,以正确打印 ASCII 以上的字符。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <locale>
// File saved as UTF-8, with characters outside the ASCII range
int main()
{
// Set the OEM code page to be the default OS code page
setlocale(LC_ALL, "");
// äö reside outside of the ASCII range and in the Unicode code point Western Latin 1
// Thus, requires a lead byte per unicode code point when saving as UTF-8
char* hmm = "äö";
printf("UTF-8 file string using Windows 1252 code page read as:%s\n",hmm);
printf("Length:%d\n", strlen(hmm));
// Convert the UTF-8 String to a wide character
int nLen = MultiByteToWideChar(CP_UTF8, 0,hmm, -1, NULL, NULL);
LPWSTR lpszW = new WCHAR[nLen];
MultiByteToWideChar(CP_UTF8, 0, hmm, -1, lpszW, nLen);
// Print it
wprintf(L"wprintf wide character of UTF-8 string: %s\n", lpszW);
// Free the memory
delete[] lpszW;
int c = getchar();
return 0;
}
UTF-8 file string using Windows 1252 code page read as:äö
Length:4
wprintf wide character of UTF-8 string: äö