将多字节存储到char数组中

时间:2018-08-23 03:43:45

标签: c unicode

以下代码有效:

char *text = "中文";
printf("%s", text);

然后,我尝试通过它的Unicode代码点来打印此文本,该代码点的“中”是0x4e2d,而“文”是0x6587enter image description here

当然,什么也没打印出来。

我试图了解将多字节字符串存储到char*中并如何使用unicode代码点打印多字节字符串时发生的情况,并且, “ Format specifier '%ls' requires 'wchar_t *' argument instead of 'wchar_t *'是什么意思?

感谢您的帮助。

编辑: 我在Mac OSX(高Sierra 10.13.6)上运行 enter image description here

$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix

1 个答案:

答案 0 :(得分:3)

  wchar_t *arr = malloc(2 * sizeof(wchar_t));
  arr[0] = 0x4e2d;
  arr[1] = 0x6587;

首先,以上字符串不是以空值结尾的。 printf函数知道数组的开始,但是不知道数组的结尾或数组的大小。您必须在末尾添加一个零来制作以N结尾的C字符串。

要打印此以空值结尾的宽字符串,请在基于Unix的计算机(包括Mac)上使用"printf("%ls", arr);",在Windows中使用"wprintf("%s", arr);"(这是完全不同的事情,它实际上将字符串视为UTF16)。

对于基于Unix的计算机,请确保添加setlocale(LC_ALL, "C.UTF-8");setlocale(LC_ALL, "");

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main() 
{
    setlocale(LC_ALL, "C.UTF-8");

    //print single character:       
    printf("%lc\n", 0x00004e2d);
    printf("%lc\n", 0x00006587);
    printf("%lc\n", 0x0001F310);

    wchar_t *arr = malloc((2 + 1)* sizeof(wchar_t));
    arr[0] = 0x00004e2d;
    arr[1] = 0x00006587;
    arr[2] = 0;
    printf("%ls\n", arr);

    return 0;
}

放在一边

在UTF32中,代码点始终需要4个字节(示例0x00004e2d),可以用4个字节的数据类型char32_t(或POSIX中的wchar_t)表示。

在UTF8中,代码点需要1、2、3或4个字节。 ASCII字符的UTF8编码需要一个字节。 需要3个字节(或3个char值)。您可以通过运行以下代码来确认这一点:

printf("A:%d 中:%d :%d\n", strlen("A"), strlen("中"), strlen(""));

例如,我们不能在UTF8中使用单个char。我们可以改用字符串:

const char* x = u8"中";

我们可以在C中使用普通的字符串函数,例如strcpy等。但是某些标准C函数不起作用。例如,strchr不能找到。这通常不是问题,因为诸如“打印格式说明符”之类的字符全为ASCII且为一个字节。