c - iconv - 保留无法转换为 ascii 的字符
问题描述
我正在使用 iconv 的音译函数将 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
不支持您希望开箱即用的转换行为,因为这是一种非常奇怪的行为:如果可以在输出中有一个 ∑,为什么在输出中有一个 ß 就不行输出?
无论如何,您可以通过您自己的一个使用 iconv 的函数来实现这种转换,如下所示:
- 分配两个转换描述符:
iconv_t cd0 = iconv_open("UTF-8", "UTF-8"); iconv_t cd1 = iconv_open("ASCII//TRANSLIT", "UTF-8");
- 使用一个循环,通过 iconv() 重复转换部分字符串
cd1
。当调用失败并显示 errno == EILSEQ 时,您知道这是因为无法音译为 ASCII 的字符。 - 此时使用带有
cd0
, 的 iconv() 调用来转换一个且只有一个字符。您可以通过在 in = 1 时调用 iconv() 来执行此操作,然后如果在 in = 2 时失败,依此类推直到 in = 4。(如果所有这些都失败,则您必须输入无效;最好的选择是跳过一个输入字节并在输出中留下一个“?”。) - 单个字符的no-op转换后,返回步骤2。
推荐阅读
- java - Spring JPA Hibernate 无法自动生成 Id H2 表
- r - 等效于 ggplot 中的验证图
- r - 使用 R 中的 apply 函数处理隐式对象
- angular - Angular:从 Spotify 请求访问令牌时,HTTP 发布请求错误“grant_type 参数丢失”
- python - 生成每行中具有上限和下限的二进制随机矩阵?
- typescript - 确定类型取决于接口中其他键的值(TypeScript)
- javascript - Sinusbot 脚本:如何检测客户端何时在频道中移动?
- javascript - 如何在 javascript 中读取 cvs 文件并将它们存储在地图中?
- regex - 正则表达式从 url 中提取链接
- django - 在尝试将我的 django 应用程序部署到 heroku 时,我不断收到错误消息:[远程拒绝] master -> master (pre-receive hook denied)