#1
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main()
{
setlocale(LC_CTYPE,"C");
wprintf(L"大\n");
return 0;
}
//result : ?
#2
#include <stdio.h>
#include <locale.h>
int main()
{
setlocale(LC_CTYPE,"C");
printf("大\n");
return 0;
}
//result : 大
#1 和#2 的区别只是打印功能。
我希望如果宽字符没有在某些区域设置中打印,那么多字节字符也不应该在同一区域设置中打印。
我很好奇为什么打印多字节字符串(#2),而不打印宽字符串(#1)?
我知道如果语言环境不是
"C"
,宽字符会打印得很好。但为什么??区域设置到底是做什么的?
+)我认为多字节字符编码与区域设置相关,但是多字节字符打印得很好,与区域设置无关。.计算机如何确定多字节字符编码?
如果您使用
Windows Console
,如果您想使用宽字符串,则应使用 _setmode
函数将 stdout
的默认翻译模式更改为 Unicode。
例如:
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#include <fcntl.h>
#include <io.h>
int main()
{
setlocale(LC_CTYPE,"C");
_setmode(_fileno(stdout), _O_U16TEXT);
wprintf(L"大\n");
return 0;
}
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=msvc-170
L”大 " 是一个包含 3 个元素的 wchar_t 数组。
数组[0] == L'大'(0xE5 0xA4 0xA7)
数组[1] == 换行符(0xA)
数组[2] == null (0x0)
但是 C 语言环境不理解位置 0 处的第一个多字节字符。
“大 " 创建一个包含 5 个元素的 char(字节)数组。
数组[0] == (0xE5)
数组[1] == (0xA4)
数组[2] == (0xA7)
数组[3] == 换行符(0xA)
数组[4] == null (0x0)
打印第二个,因为它实际上创建了一个短字符数组。当您打印字符串时,它只是将每个字节发送到屏幕,直到到达空字符。
它在你的屏幕上打印为“大”,因为你的操作系统会这样对待该字节序列。
#include <stdio.h>
#include <stdlib.h>
int main() {
char first_byte = strtol("0xE5", NULL, 16);
char second_byte = strtol("0xA4",NULL,16);
char third_byte = strtol("0xA7",NULL,16);
printf("%c%c%c\n", first_byte, second_byte, third_byte);
return 0;
}
输出:大