除了使用字符串文字之外,还有其他方法可以在 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_tchar 一样,都是整数类型。如果您需要计算字符代码(例如非拉丁数字),这有时会很有用,但通常认为使用宽字符文字会更好。

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

【讨论】:

以上是关于除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?的主要内容,如果未能解决你的问题,请参考以下文章

除了适配器之外,还有其他方法可以将数据实现到活动中吗?

除了使用 A* 之外,还有其他优化 Dijkstra 算法的方法吗?

除了按位与之外还有其他用途吗[重复]

Android:除了 Location.getAltitude() 之外,还有其他方法可以获取高度吗? (我听说过使用传感器)

除了 Cocoapods 之外,还有其他方法可以将 Firebase 整合到我的 iOS 应用程序中吗?

除了通过 main 的 argv 之外,还有其他方法可以将用户参数传递给程序吗?