临时小驻

求仁得仁,复无怨怼。

了解 char, wchar_t 和其他衍生类型

2018-08-22 14:59:00 +0800

UCS-2 是每个 Unicode 字符占 2B 的编码格式,又称 UTF-16;UCS-4 是 4B,又称 UTF-32。UCS-4 是 UCS-2 的超集。

c 中 stddef.h 定义了 wchar_t。可以在 wchar.h 里找到更多有关 wchar_t 的函数。

Windows 使用 UCS-2 标准,即 wchar_t 占 2B;Linux 使用 UCS-4 标准,即 wchar_t 占 4B。

请看下例:

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

#if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000
#   define SIZEOFWCHAR (4)
#   define SIZEOFWCHAR_STR "8"
#else
#   define SIZEOFWCHAR (2)
#   define SIZEOFWCHAR_STR "4"
#endif

void dump_chars(char *s) {
    unsigned char *p = s;
    while (*p) {
        printf("%02x ", *p);
        p++;
    }
    printf("\n");
}

void dump_wchars(wchar_t *ls) {
    wchar_t *p = ls;
    while (*p) {
        printf("%0" SIZEOFWCHAR_STR "x ", *p);
        p++;
    }
    printf("\n");
}

int main() {
    // 需要这句来保证 %ls 正常输出
    setlocale(LC_ALL, "");

    printf("%lu %lu\n", sizeof(char), sizeof(wchar_t));
    // 在 win64   vc++ 上得到 1 2
    // 在 linux64 gcc  上得到 1 4

    char *s = "Hi 你好";
    printf("%s\n", s);

    dump_chars(s);
    // 48 69 20 e4 bd a0 e5 a5 bd

    wchar_t *ls = L"Hi 你好";
    printf("%ls\n", ls);

    dump_wchars(ls);
    // win64   vc++ : 0048 0069 0020 4f60 597d
    // linux64 gcc  : 00000048 00000069 00000020 00004f60 0000597d

    return 0;
}

可以看到,在 (unsigned) char * 里是以 UTF-8 编码保存的,在 wchar_t * 里是以 UTF-16 / UTF-32 编码保存的。

注意,在一个程序中,printf()wprintf() 不能一起用。

通常,我们称 char * 表示的字符串是 narrow string;称 wchar_t * 表示的字符串是 wide string。

vc++ 定义了很多与此相关的概念:

NPSTR = Near Pointer to String
LPSTR = Long Pointer to String
PSTR = Pointer to String, char *
PWSTR = Pointer to Wide String, wchar_t *
PCSTR = Pointer to Constant String, const char *

这里的 Near、Long 是相对于 16 位程序来说的,因此在 32 位下这两者已无意义, PSTR == LPSTR == NPSTR

这些前缀排列组合就可以见到诸如 LPCWSTR = Long Pointer to Constant Wide String = PCWSTR (const wchar_t *) 这样的类型。

为了允许创建能兼容 ANSI 和 Unicode 的程序,vc++ 还提供了一组 TSTR 类型。

#ifdef UNICODE
typedef WCHAR       TCHAR;
#else
typedef CHAR        TCHAR;
#endif

自然也有包括 LPCTSTR (const TCHAR *) 这样的类型。

原文链接 https://blog.xupu.name//p/2018-08-understanding-char-and-wchar-t/

如无特别指明,本站原创文章均采用 CC BY-NC-ND 4.0 许可,转载或引用请注明出处,更多许可信息请查阅这里