宽字符和区域设置

问题描述 投票:0回答:2

#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"
,宽字符会打印得很好。但为什么??区域设置到底是做什么的?

+)我认为多字节字符编码与区域设置相关,但是多字节字符打印得很好,与区域设置无关。.计算机如何确定多字节字符编码?

c encoding locale
2个回答
0
投票

如果您使用

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


0
投票
  1. L”大 " 是一个包含 3 个元素的 wchar_t 数组。

    数组[0] == L'大'(0xE5 0xA4 0xA7)

    数组[1] == 换行符(0xA)

    数组[2] == null (0x0)

但是 C 语言环境不理解位置 0 处的第一个多字节字符。

  1. “大 " 创建一个包含 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;
}

输出:大

© www.soinside.com 2019 - 2024. All rights reserved.