c - 为什么作为命令行参数传入的 UTF-16 字符串的 hexdump 与直接在终端上的不同?

标签 c bash utf-16 hexdump libiconv

在 bash 中,我可以通过执行以下操作将字符串 hello 的 hexdump 获取为 UTF-16:

$  echo -n "hello" | iconv -f ascii -t utf-16 | hexdump
0000000 feff 0068 0065 006c 006c 006f          
000000c

我也可以像这样写一个简短的 C 程序:

int main(int argc, char **argv) {
  char *str = argv[1];

  hexDump("The string", str, 12);

  return 0;
}

使用来自 how to get hexdump of a structure datahexDump 例程. 12 是我使用上面的 hexdump 计算的字节数。

编译运行:

$ gcc test.c -o test


$ ./test $(echo -n hello | iconv -f ascii -t utf-16)
The string:
  0000  ff fe 68 65 6c 6c 6f 00 53 53 48 5f              ..hello.SSH_

为什么第一个十六进制字符串 feff 0068 0065 006c 006c 006f 和第二个十六进制字符串 ff fe 68 65 6c 6c 6f 00 53 53 48 5f 有区别?

我问这个是因为我正在尝试调试一个应用程序,该应用程序使用 libiconv 将 UTF-16 字符串转换为 UTF-8 并不断获取 errno EILSEQ 这意味着 libiconv 遇到了“无效的多字节序列”。

更新:

如果我使用 -C 运行 hexdump,我会得到以下输出:

$ echo -n hello | iconv -f ascii -t utf-16 | hexdump -C
00000000  ff fe 68 00 65 00 6c 00  6c 00 6f 00              |..h.e.l.l.o.|
0000000c

这个 hexstring 仍然不同于我的 C 程序生成的那个,因为它包含散布在 ascii 字符之间的 \x00 字节。但是,当我运行 C 程序时,根本没有散布 \x00 字节。它只有 ff fe header ,然后是常规的 ascii 字符。

最佳答案

命令 echo -n hello | iconv -f ascii -t utf-16 | hexdump -C 只是直接在程序之间传输数据。 iconv 输出的任何字节都直接作为 hexdump 的输入。

使用命令 ./test $(echo -n hello | iconv -f ascii -t utf-16),shell 获取 iconv 的输出,并将其有效地粘贴到新命令中, 解析新命令,然后执行它。

因此来自 iconv 的字节是:“ff fe 68 00 65 00 6c 00 6c 00 6f 00”,shell 对此进行解析。看起来好像 shell 在解析时只是简单地跳过空字节,所以输入到程序的参数只是非空字节。由于您的字符串是 ascii,这意味着结果只是一个 ascii 字符串(前面是 UTF-16 BOM)。

我们可以使用 U+3300 (㌀) 这样的字符来演示这一点。如果我们传递这个而不是 ascii 字符并且上面是正确的,那么输出将包括 0x33(数字“3”)。

./test $(echo -n ㌀ | iconv -f utf-8 -t utf-16)

我的终端碰巧使用 UTF-8,它支持字符 U+3300,所以我让 iconv 将其转换为 UTF-16。我得到输出:

The string:
  0000  ff fe 33                                         ..3

顺便说一下,您的程序包含数组的硬编码大小:

hexDump("The string", str, 12);

你真的不应该那样做。如果数组不是那么大,那么你会得到未定义的行为,并且你的帖子显示在真正的参数之后打印出一些垃圾(垃圾似乎是环境变量数组的开头)。这真的没有理由。只需使用正确的值:

hexDump("The string", str, strlen(str));

关于c - 为什么作为命令行参数传入的 UTF-16 字符串的 hexdump 与直接在终端上的不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21058436/

相关文章:

node.js - bash:npm:在 cPanel 终端中找不到命令

ruby - 当编码全部被破坏时,如何使用 Ruby 替换 VC++ 资源文件中的文本?

iphone - 我在作业中得到不兼容的类型?

c - Reader - Writer 互斥体

bash - 在 bash 中传递换行符(LF)/换行符作为参数

c++ - utf-8 与 utf-16 之间的问题

c - 按字符读取 UTF-16 CSV 文件

C 编程 - 矩阵索引 X 和 Y

C和64位指针计算

bash - 关于 $SHLVL 的 Zsh 怪异