我正在尝试打印放大镜(http://www.fileformat.info/info/unicode/char/1f50e/index.htm),我收到此错误:
[niko@dev1 ncurses]$ gcc -o utf8 -std=c99 $(ncursesw5-config --cflags --libs) utf8.c
utf8.c: In function ‘main’:
utf8.c:12:10: error: \ud83d is not a valid universal character
printw("\ud83ddd0e\n"); // escaped Unicode
^
[niko@dev1 ncurses]$ cat utf8.c
#include <locale.h>
#include <curses.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
setlocale(LC_ALL, "");
initscr();
printw("\ud83ddd0e\n"); // escaped Unicode
getch();
endwin();
return EXIT_SUCCESS;
}
这是什么问题?例如,如果我有一个十进制数的编码,对于放大镜是55357,我将如何在printf中打印到ncurses屏幕? (不使用wchar_t,因为它浪费了大量内存)
答案 0 :(得分:5)
有关fileformat.info的信息有误。页面上的转义为\ud83d\udd0e
。这是在Java上使用的UTF-16代理对,但它不适用于C,因为GCC似乎要求一个\u
转义表示一个Unicode代码点,而代理转义的一半不是。
您应该使用带有8个十六进制数字的\U
(大写),因此U + 1F50E变为\U0001F50E
。使用printf
正确输出此转义字符。
PS:如果您使用~_~T~N
而不是放大镜,请确保您已调用setlocale
并实际链接到-lncursesw
,否则无法执行任何操作意味着将打印垃圾。
答案 1 :(得分:1)
您不应该使用UTF-16(sport
)对字符串进行编码,而应使用UTF-8编码。要转换它,请运行以下命令:
category
然后,你可以看到你的角色是U + 0001F50E。要在C代码中插入此字符,请使用带有大写字母U的<{1}}序列。
\ud8..\udd..
顺便说一句,你的号码55357不是放大镜(U + 1F50E),而只是用UTF-16编码的放大镜的前半部分。
答案 2 :(得分:-1)
您可以使用putwchar(请参阅http://www.cplusplus.com/reference/cwchar/putwchar/)打印wchar,但我不相信它适用于UTF-16代理对。
在任何情况下,将unicode文本打印到终端始终是未定义的行为。在unix系统上,大多数终端模拟VT-100,并且只保证支持7位ASCII文本。 (这就是isprint
函数存在的原因)。
您最好的选择是使用像freetype2或cairo + pango这样的库来将文本渲染到图形应用程序中的曲面或像素图。