除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?
Are there other ways to specify or enter a Unicode code point in C other than using string literals?
在下面的程序中,我尝试向 ncurses 函数 setcchar() 提供一个 Unicode 代码点作为数组字符串而不是字符串文字。但是我得到的输出只是数组的第一个字符,即反斜杠字符。
除了作为字符串文字之外,还有其他方法可以指定 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'[=10=]';
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;
}
包含六个字符的数组 \u4e09
是包含六个字符的数组,就像包含反斜杠后跟 n
的数组是两个字符的数组,而不是换行符。 编译器 将转义序列转换为文字。没有任何东西(除了你自己写的)对字符数组有任何作用。
所以你的数组 wcsarr
不是一个单一的宽字符。它是一个(以 null 结尾的)宽字符串,使用六个 wchar_t 值来编码六个 ascii 字符。 setcchar
要求它的第二个参数只包含一个空格字符(后面可能跟几个非空格组合字符),你的程序不符合这个规范。
你可以这样做:
wchar_t wcsarr[] = {0, 0};
wcsarr[0] = L'\u4e09`;
如果您知道您的语言环境使用 Unicode 代码点作为宽字符代码,您可以这样写:
wcsarr[0] = 0x4e09;
因为 wchar_t
和 char
一样是整数类型。如果您需要计算字符代码(例如非拉丁数字),这偶尔会有用,但通常使用宽字符文字被认为是更好的风格。
如果你真的需要解码包含转义序列的字符串,你需要验证语法是否正确,然后使用类似 strtol
的东西,基本参数设置为 16。注意,但是,strtol
没有任何机制将其参数限制为正好四位数字,因此如果转义序列出现在文本中,并且它后面可能跟一个看起来像十六进制数字的内容,则您将不得不以某种方式提取它.要么将其复制到临时缓冲区,要么在字符串可以修改的情况下以 null 终止它。或者您可以编写自己的十六进制解码器;不难
在下面的程序中,我尝试向 ncurses 函数 setcchar() 提供一个 Unicode 代码点作为数组字符串而不是字符串文字。但是我得到的输出只是数组的第一个字符,即反斜杠字符。
除了作为字符串文字之外,还有其他方法可以指定 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'[=10=]';
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;
}
包含六个字符的数组 \u4e09
是包含六个字符的数组,就像包含反斜杠后跟 n
的数组是两个字符的数组,而不是换行符。 编译器 将转义序列转换为文字。没有任何东西(除了你自己写的)对字符数组有任何作用。
所以你的数组 wcsarr
不是一个单一的宽字符。它是一个(以 null 结尾的)宽字符串,使用六个 wchar_t 值来编码六个 ascii 字符。 setcchar
要求它的第二个参数只包含一个空格字符(后面可能跟几个非空格组合字符),你的程序不符合这个规范。
你可以这样做:
wchar_t wcsarr[] = {0, 0};
wcsarr[0] = L'\u4e09`;
如果您知道您的语言环境使用 Unicode 代码点作为宽字符代码,您可以这样写:
wcsarr[0] = 0x4e09;
因为 wchar_t
和 char
一样是整数类型。如果您需要计算字符代码(例如非拉丁数字),这偶尔会有用,但通常使用宽字符文字被认为是更好的风格。
如果你真的需要解码包含转义序列的字符串,你需要验证语法是否正确,然后使用类似 strtol
的东西,基本参数设置为 16。注意,但是,strtol
没有任何机制将其参数限制为正好四位数字,因此如果转义序列出现在文本中,并且它后面可能跟一个看起来像十六进制数字的内容,则您将不得不以某种方式提取它.要么将其复制到临时缓冲区,要么在字符串可以修改的情况下以 null 终止它。或者您可以编写自己的十六进制解码器;不难