在 C 中,如果在 char 变量中给出 UTF-8 字符的字节,如何打印?

In C, how to print UTF-8 char if given its bytes in char variables?

提问人:SO Stinks 提问时间:10/1/2022 更新时间:10/4/2022 访问量:548

问:

如果我有 c1、c2 作为 char 变量(使 c1c2 将是 UTF-8 字符的字节序列),我该如何创建和打印 UTF-8 字符?

同样,对于 3 字节和 4 字节的 UTF-8 字符?

我一直在尝试各种方法,但我就是无法让它起作用。mbstowcs()

c utf-8 wchar-t wchar

评论

0赞 Craig Estey 10/1/2022
我最近对 utf-8 的回答可能会有所帮助:在 C 语言的二维数组中搜索字母
0赞 JosefZ 10/1/2022
编辑您的问题,以提供一个最小的可重复示例
0赞 Giacomo Catenazzi 10/3/2022
一般来说,在 UTF-8 中:“char”只是“byte”的错误名称。真正的 Unicode 字符应由字符串表示。MB 通常无济于事。

答:

1赞 qrsngky 10/4/2022 #1

我设法写了一个工作示例。
当 is 和 is 时,结果是 。
原来,我必须在使用前打电话。
c1'\xce'c2'\xb8'θsetlocalembstowcs

#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
 
int main()
{
   char* localeInfo = setlocale(LC_ALL, "en_US.utf8");
   printf("Locale information set to %s\n", localeInfo);
   
   const char c1 = '\xce';
   const char c2 = '\xb8';
   int byteCount = 2;

   char* mbS = (char*) malloc(byteCount + 1);
   mbS[0] = c1; 
   mbS[1] = c2; 
   mbS[byteCount] = 0; //null terminator
   printf("Directly using printf: %s\n", mbS);
   
   
   int requiredSize = mbstowcs(NULL, mbS, 0); 
   printf("Output size including null terminator is %d\n\n", requiredSize +1);
   
   wchar_t *wideOutput = (wchar_t *)malloc( (requiredSize +1) * sizeof( wchar_t ));
   
   int len = mbstowcs(wideOutput , mbS, requiredSize +1 ); 
   if(len == -1){
       printf("Failed conversion!");
   }else{
       printf("Converted %d character(s). Result: %ls\n", len, wideOutput );
   }
   return 0;
    
}

输出:

Locale information set to en_US.utf8
Directly using printf: θ
Output size including null terminator is 2

Converted 1 character(s). Result: θ

对于 3 或 4 字节的 utf8 字符,可以使用类似的方法。

1赞 KamilCuk 10/4/2022 #2

如果我有 c1、c2 作为 char 变量(使 c1c2 将是 UTF-8 字符的字节序列),我该如何创建和打印 UTF-8 字符?

它们已经 UTF-8 字符。你只需打印它们。

putchar(c1);
putchar(c2);

这取决于您的终端或您用来显示输出的任何设备,以正确理解和呈现 UTF-8 编码。这与程序使用的编码无关,也与宽字符无关。

同样,对于 3 字节和 4 字节的 UTF-8 字符?

您将输出它们。


如果您的终端或您要向其发送字节的设备不理解 UTF-8 编码,则必须将字节转换为设备可以理解的内容。通常,您将为此使用外部库,例如 .或者,您可以将字节转换为 ,然后再将字节转换为该编码,或者使用 输出字节。所有(在常见系统上)都是将字符串转换回多字节然后输出它。输出到终端的宽流也做同样的事情,首先转换,然后输出。iconvsetlocale("C.utf-8")wchar_tsetlocale("C.your_target_encoding")%ls%ls