【问题标题】:Read bytes from int to write Unicode C [closed]从 int 读取字节以写入 Unicode C [关闭]
【发布时间】:2018-03-01 00:24:40
【问题描述】:

简而言之,我试图从int c = L'☺'; 获取这些{0xe2, 0x98, 0xba},除了unistd 之外没有任何库。

我知道这与位掩码有关,但经过几个小时无处可去后,我需要帮助。

谢谢!

【问题讨论】:

  • 您要获取的值是 UTF-8。您需要对其进行转换。
  • 不要自己滚动这个。那些在“如何读入/写出 unicode”问题(这是一个非常复杂的主题)上花费了比健康更多的时间的人编写了出色的库来为你解决这个问题。
  • 在什么操作系统(和版本)和编译器(和版本)和编译标志上?
  • "几个小时后一无所获" --> 发布你所做/绑定的内容会改进这篇文章。
  • 我不能使用任何外部库@Mike'Pomax'Kamermans

标签: c unicode bit-manipulation


【解决方案1】:

使用一些 UTF-8/Unicode 库,如libunistring;许多库具有 UTF8 相关功能,例如Glib。 C11 有 一些 multibyte character 支持(因此请检查您的实现是否使用 UTF8...)

阅读更多关于UnicodeUTF-8的信息,包括http://utf8everywhere.org/

也许您的操作系统或 C 实现提供了一些东西。

UTF-8 和 Unicode 很复杂(带有微妙的极端情况);所以避免重新发明轮子并尝试自己制作一些功能。

L'☺' 可能在 Windows 和 Linux 上的含义有所不同(例如,因为 sizeof(wchar_t) 可能不同;它可能是 16 位或 32 位)。您的 C 源文件可以是 UTF8 编码的(经常是这种情况)但可能不是,所以您的源代码中的 L'☺' 到底是什么是有争议的。

(理论上源代码可能不是UTF8)

为了安全,最好坚持使用 UTF-8,假设并记录 C 源文件和实现都使用 UTF-8,所以使用UTF-8 everywhere,不带任何wchar_tL'☺',并有一个@ 987654336@ 字符串(而不是 "☺"),也许在 comment 中提到它是 /*U+263A WHITE SMILING FACE ☺*/;或者至少使用字符串"☺",但避免使用宽字符。

换句话说,我听说包含L'☺' 的源代码不能在Windows 和Linux 之间移植(但我不在乎,因为我从未使用过Windows)。因此,出于可移植性的原因,至少更喜欢使用像 "☺" 这样的文字字符串(但 "\342\230\272" 更好)并明确记录在您的源代码和应用程​​序的输入和输出中使用的编码(最好是 UTF-8)。

Character encoding 可能会成为一场噩梦。你会找到像libiconv 这样的库来处理这个问题。但在 2017 年使用 UTF-8 everywhere(在您的 C 源代码和程序的输出中)因此避免在您的源代码中使用 L'☺'

【讨论】:

  • 或者,根据他使用的操作系统,系统 API 中可能包含一些相当不错的 Unicode 功能。
【解决方案2】:

如果你有一个 C11 编译器,它有一个支持 unicode 的标准头文件。你想要例程 c32rtomb:

#include <uchar.h>

char buffer[4];
len = c32rtomb(buffer, L'☺', 0);

【讨论】:

  • 您确定每个 C11 实现都使用Unicode 或UTF8 吗? (基于 EBCDIC 的呢)。 AFAIK 一些 C 实现有 32 位 char-s 并且标准允许这样做
  • 它是 C11 标准的一部分。当然,很多 C 编译器仍然没有正确实现 C99,更不用说 C11。
  • 标准的组成部分是什么? c32rtomb 还是 UTF8?超过 8 位 char-s 的实现呢? (我很确定标准允许这样做,即使我不知道有很多实现这样做)。 wchar_t 在不同的实现上也有不同的大小(这就是为什么它不是很有用)
  • uchar.h 和 c32rtomb 是标准的一部分
  • 但请注明在哪里提到了 UTF8 或 Unicode。 IIRC 没那么简单! (因为 16 位或 32 位 char-s 是可能的)
【解决方案3】:

从 int 读取字节以写入 Unicode C
我正在尝试从int c = L'☺';

获取这些 {0xe2, 0x98, 0xba}

如果代码可以从 UTF-8 字符串文字开始,建议:

#include <stdio.h>

int main(void) {
  char *s = u8"☺";
  printf("0x%02hhx 0x%02hhx 0x%02hhx\n", s[0], s[1], s[2]);
  return 0;
}

输出

0xe2 0x98 0xba

要生成整数,请使用足够宽的整数类型,例如 uint32_t 和值 s[0], s[1], s[2]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多