1

如果我写:

char a = 'A';
printf("%x %c", a, a);

它将产生输出“41 A”。我写的时候也一样

char32_t c = U'';
printf("%x %c", c, c);  //even tried %lc and %llc

它将产生输出“1f34c L”而不是预期的“1f34c”!

这里有什么问题吗?如何将 char16_t 和 char32_t 字符打印到标准输出?

另外,我应该使用哪个格式说明符从 scanf 获取 char16_t / char32_t 输入?

char32_t c;
scanf("%c", &c); //
printf("%x %c", c, c);

这将产生输出“f0 �”。

4

2 回答 2

2

我已经在HEX格式中给出了值,symbol = 0x0001F34C还有其他方法可以解决这个问题,这就是我如何知道在 c 中检查以下代码,我们无法使用打印符号,%c或者只是printf 在这里解释为什么使用 wchar_t 而不是 char char具有 UTF-8 编码而 wchar_t 具有 UTF -32 增加其范围

#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
    setlocale(LC_CTYPE, "");
    wchar_t symbol = 0x0001F34C;
    wprintf(L"%x %lc\n",symbol,symbol);
}
output: 1f34c 

检查以下链接 在 C中打印 Unicode 符号,表情符号香蕉的 UNICODEchar32_t

于 2021-03-29T06:54:13.627 回答
2

char16_tchar32_t没有什么特别的。他们真的只是uint_least16_tuint_least32_t。他们没有那么大的支持。u它们的唯一用途基本上是U文字。它们可能不是UTF-16 和 UTF-32 -在假设它们是之前检查__STDC_UTF_16__和宏。__STDC_UTF_32__只有非常基本的转换函数是标准的。在标准中,只有转换char16_t或转换char32_t为多字节编码并返回的功能。要对它们做更多的事情,你必须自己实现它。

C 语言实际上有两种编码——依赖于语言环境的多字节字符表示和宽字符表示。

这里有什么问题吗?

您在源文件''中键入的字符被编译器解释为某个特定于实现的值。Gcc 会生成一个 UTF-8,然后gcc 预处理器会将值向左移动,所以等于gcc - 多字符文字的行为 是实现定义的。然后将该字符的值分配给。这根本不是 UTF-32 值。''(int)0xF09F8D8C 'something'char32_t

如何将 char16_t 和 char32_t 字符打印到标准输出?

将它们转换为多字节字符串。然后用%s.

#include <stdlib.h>
#include <uchar.h>
#include <stdio.h>
#include <wchar.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <locale.h>
int main() {
    setlocale(LC_ALL, "en_US.UTF-8");
    char32_t c = U'';
    char buf[MB_LEN_MAX + 1] = {0};
    mbstate_t ps;
    memset(&ps, 0, sizeof(ps));
    c32rtomb(buf, c, &ps);
    printf("%s\n", buf);
}

打印数据取决于区域设置,因为打印是在用户指定的区域设置中完成的。默认语言环境是C并且不支持 UTF。所以首先你必须将你的语言环境设置为兼容 utf 的东西。然后调用c32rtomb。请注意,流在第一次打印时选择编码glibc- 确保在对要使用的流执行任何操作setlocale 之前调用。

我应该使用哪个格式说明符从 scanf 获取 char16_t / char32_t 输入?

没有,没有。您应该使用wchar_t或纯char字符串以用户语言环境中指定的编码从用户那里读取字符。char16_t然后,您可以根据需要转换为/从char32_t。如果您想专门读取 UTF-32 字符,那么您必须自己编写以确保您的代码读取UTF-32字符。我推荐libunistring

于 2021-03-29T08:33:43.570 回答