微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?

如何解决除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?

在下面的程序中,我试图将 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",NULL);
  addstr("Code point entered as a string literal: ");
  add_wch(&kanji);
  addstr("\n");
  
  refresh();
  getch();
  endwin();

  return EXIT_SUCCESS;
}

解决方法

包含六个字符 \u4e09 的数组是包含六个字符的数组,就像包含反斜杠后跟 n 的数组是两个字符的数组,而不是换行符。 编译器 将转义序列转换为文字。没有任何东西(除了你自己写的东西)对字符数组做任何事情。

所以你的数组 wcsarr 不是单个宽字符。它是一个(以空字符结尾的)宽字符串,使用六个 wchar_t 值来编码六个 ascii 字符。 setcchar 要求它的第二个参数只包含一个空格字符(可能后跟几个非空格组合字符),并且您的程序不符合此规范。

你可以这样做:

wchar_t wcsarr[] = {0,0};
wcsarr[0] = L'\u4e09`;

如果您知道您的语言环境使用 Unicode 代码点作为宽字符代码,您可以这样写:

wcsarr[0] = 0x4e09;

因为 wchar_tchar 一样,都是整数类型。如果您需要计算字符代码(例如非拉丁数字),这有时很有用,但通常认为使用宽字符文字更好。

如果您确实需要对包含转义序列的字符串进行解码,则需要验证语法是否正确,然后使用 strtol 之类的内容并将基本参数设置为 16。但是请注意, strtol 没有任何机制将其参数限制为恰好四位数字,因此如果转义序列出现在文本中,它可能后跟看起来像十六进制数字的内容,您将不得不以某种方式提取它。如果字符串可以修改,要么将其复制到临时缓冲区,要么以空字符结尾。或者您可以编写自己的十六进制解码器;不难。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。