除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?
Posted
技术标签:
【中文标题】除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?【英文标题】:Are there other ways to specify or enter a Unicode code point in C other than using string literals? 【发布时间】:2021-08-11 18:11:09 【问题描述】:在以下程序中,我尝试将 Unicode 代码点作为数组字符串而不是字符串文字提供给 ncurses 函数 setcchar()。然而,我得到的输出只是数组的第一个字符,即反斜杠字符。
除了作为字符串文字之外,还有其他方法可以指定 Unicode 代码点吗?为什么这两个表达式 L"\u4e09" 和 wcsarr 在这种情况下不会产生相同的结果...
#define _XOPEN_SOURCE_EXTENDED 1
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
#include <time.h>
int main()
setlocale(LC_ALL, "");
cchar_t kanji;
wchar_t wcsarr[7];
wcsarr[0] = L'\\';
wcsarr[1] = L'u';
wcsarr[2] = L'4';
wcsarr[3] = L'e';
wcsarr[4] = L'0';
wcsarr[5] = L'9';
wcsarr[6] = 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;
【问题讨论】:
他们没有产生相同的结果,因为它们是两个不同的字符串?一个有六个代码点,一个有一个 CP。 不幸的是,宽字符是否使用 Unicode 取决于系统。 【参考方案1】:包含六个字符\u4e09
的数组是包含六个字符的数组,就像包含一个反斜杠后跟一个n
的数组是一个包含两个字符的数组,而不是一个换行符。 编译器 将转义序列转换为文字。没有任何东西(除了你自己写的)对字符数组有任何作用。
所以您的数组wcsarr
不是单个宽字符。它是一个(以空结尾的)宽字符串,使用六个 wchar_t 值来编码六个 ascii 字符。 setcchar
要求它的第二个参数只包含一个空格字符(可能后跟几个非空格组合字符),并且您的程序不符合此规范。
你可以这样做:
wchar_t wcsarr[] = 0, 0;
wcsarr[0] = L'\u4e09`;
如果您知道您的语言环境使用 Unicode 代码点作为宽字符代码,您可以这样写:
wcsarr[0] = 0x4e09;
因为wchar_t
和char
一样,都是整数类型。如果您需要计算字符代码(例如非拉丁数字),这有时会很有用,但通常认为使用宽字符文字会更好。
如果您确实需要解码包含转义序列的字符串,则需要验证语法是否正确,然后使用 strtol
之类的内容,并将基本参数设置为 16。但是请注意,@ 987654330@ 没有任何机制将其参数限制为精确的四位数字,因此如果转义序列出现在文本中,并且后面可能跟着看起来像十六进制数字的内容,您将不得不以某种方式提取它。将其复制到临时缓冲区,或者如果字符串可以修改,则以空值终止它。或者您可以编写自己的十六进制解码器;不难。
【讨论】:
以上是关于除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?的主要内容,如果未能解决你的问题,请参考以下文章
除了使用 A* 之外,还有其他优化 Dijkstra 算法的方法吗?
Android:除了 Location.getAltitude() 之外,还有其他方法可以获取高度吗? (我听说过使用传感器)