【问题标题】:iconv - retaining characters that cannot be converted to asciiiconv - 保留无法转换为 ascii 的字符
【发布时间】:2019-10-02 15:58:29
【问题描述】:

我正在使用 iconv 的 transliterate 函数将 unicode 字符串转换为最接近的 ASCII 等价物。但是,该字符串包含一些没有 ASCII 等效符号的符号。我想保留这些符号而不丢弃它们。

目前,这是我正在做的事情:

iconv_t cd = iconv_open("ASCII//IGNORE//TRANSLIT", "UTF-8");
const char *utf8 = "ç ß ∑ a";

char* in = const_cast<char*>(utf8);
size_t in_bytes = strlen(in);

char buf[BUFSIZ] = {};
char* out = buf;
size_t out_bytes = sizeof(buf);

iconv(cd, &in, &in_bytes, &out, &out_bytes);

printf("%s", buf);

// prints 
c ss  a

如何配置 iconv 以产生如下输出:

c ss ∑

如果 iconv 无法做到这一点,有没有办法以编程方式实现这一点?

【问题讨论】:

  • 来自文档:“iconv 函数一次转换一个多字节字符”
  • 这似乎是一件很奇怪的事情:D 你打算用这个有趣的功能做什么?
  • 嗯,首先,您发布的命令不会在我的机器上产生该输出,而是出错(可能删除//IGNORE?)。其次,iconv 只是一个简单的命令行实用程序,在 C 程序中,您应该能够尝试自己翻译每个 Unicode 代码点并查看结果。你写了什么没用?您应该添加相关的 C 代码。
  • 我已经添加了实际代码。

标签: c ascii iconv libiconv


【解决方案1】:

iconv 不支持您希望看到的开箱即用的转换行为,因为这是一种非常奇怪的行为:如果可以在输出中有一个 ∑,为什么它没有 OK输出中有一个ß?

无论如何,你可以通过你自己的一个函数来实现这个转换,它使用iconv,如下:

  1. 分配两个转换描述符:
    iconv_t cd0 = iconv_open("UTF-8", "UTF-8");
    iconv_t cd1 = iconv_open("ASCII//TRANSLIT", "UTF-8");
    
  2. 使用循环重复转换部分字符串,通过 iconv() 和cd1。当调用失败并显示 errno == EILSEQ 时,您知道这是因为无法音译为 ASCII 的字符。
  3. 此时使用带有cd0 的iconv() 调用来转换一个且只有一个字符。您可以通过使用 in = 1 调用 iconv() 来执行此操作,然后如果失败则使用 in = 2,依此类推直到 in = 4。(如果所有这些都失败,则您必须输入无效输入;最好的选择是跳过一个输入字节并在输出中留下一个“?”。)
  4. 单个字符无操作转换后,返回步骤2。

【讨论】:

    猜你喜欢
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 2016-08-31
    相关资源
    最近更新 更多