C语言除字符串字面量外指定Unicode码点的方法及setcchar调用问题
问题解答
两类表达式结果不一致的原因
\u是C标准规定的编译期转义序列,仅在字符串/字符字面量中生效:编译器在预处理阶段扫描到字面量里的\u4e09时,会直接将其转换为对应Unicode码点U+4E09的宽字符值,最终L"\u4e09"本质是一个长度为1的宽字符数组,仅存储「三」对应的码点值+末尾终止符。
而你手动构造的wcsarr是运行期生成的普通字符序列,存储的是\、u、4、e、0、9共6个独立的宽字符,没有任何编译期处理会把这串字符自动转换为对应的Unicode码点。setcchar处理宽字符串时,会将第一个字符作为主显示字符,后续字符作为组合修饰字符,因此最终只会输出第一个字符反斜杠。
无需字符串字面量指定Unicode码点的方法
- 直接赋值码点数值:宽字符本质是整数类型,你可以直接把Unicode码点的十六进制值赋值给
wchar_t变量,这是最简便的方案:wchar_t wcsarr[2]; wcsarr[0] = 0x4E09; // 直接赋值U+4E09的数值 wcsarr[1] = L'\0'; - 运行期解析转义序列:如果你的码点字符串是运行时动态生成的(比如从配置文件、用户输入读取的
\u4e09格式字符串),可以自行写解析逻辑,提取4位十六进制数转换为整数后赋值给wchar_t。 - 多字节字符串转换:如果是UTF-8编码的多字节字符串,可以用标准库的
mbstowcs函数将其转换为宽字符数组后传入setcchar。
修正后的可运行代码示例
#define _XOPEN_SOURCE_EXTENDED 1 #include <curses.h> #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <wchar.h> int main() { setlocale(LC_ALL, ""); cchar_t kanji; wchar_t wcsarr[2]; wcsarr[0] = 0x4E09; // 直接赋值码点数值 wcsarr[1] = L'\0'; initscr(); setcchar(&kanji, wcsarr, WA_NORMAL, 5, NULL); addstr("Code point entered as an array string: "); add_wch(&kanji); addstr("\n"); setcchar(&kanji, L"\u4e09", WA_NORMAL, 5, NULL); addstr("Code point entered as a string literal: "); add_wch(&kanji); addstr("\n"); refresh(); getch(); endwin(); return EXIT_SUCCESS; }
内容的提问来源于stack exchange,提问作者Rafael X Villalobos
相关产品推荐
相关产品推荐

