如果我用 C 写一行非常简单的代码:
printf("Ascii char for %d is %c\n",65,65);
它只是打印A
,因为 ascii 值 65 对应于字符A
。但是如果我在 shell 中使用相同的代码并编写命令
printf "Ascii char for %d is %c\n" 65 65
它显示输出为Ascii char for 65 is 6
.我期望得到与 C 语言相同的输出,并且从逻辑上讲它也应该打印与给定 ascii 代码相对应的字符。
为什么它在这些情况下表现出不同的行为?
答案1
接受%c
一个字符串并打印该字符串的第一个字符。如果字符串是65
,如您的示例所示,那么它将打印6
。
转换说明符的参数
c
可以是包含零个或多个字节的字符串。如果它包含一个或多个字节,第一个字节应被写入并且任何附加字节都应被忽略。如果参数是空字符串,则未指定是否不写入任何内容或写入空字节。参数操作数应被视为字符串如果相应的转换说明符是
b
,c
, 或s
[...]
这意味着论证格式的%c
解释在 C 中(其中一个小的正整数将被转换为 a char
)和在 shell 中(其中相同的整数仍然是包含多个数字字符的字符串)。不过,格式本身也做了同样的事情;它输出一个字节作为一个字符。
然而:
$ printf '%d %b\n' 65 '\0101'
65 A
101 是八进制的 65。%b
在 POSIX 中指定为
b
应支持附加转换说明符字符 ,如下所示。该参数应被视为可以包含<backslash>
转义序列的字符串。 [...]
\0ddd
,其中ddd
是零、一位、两位或三位八进制数,应转换为具有由八进制数指定的数值的字节。
这是一个额外的转换说明符,因为它在标准 C 中不可用。但是在 shell 中需要它,因为我们没有类型变量(在 POSIX shell 中)。
还:
$ printf '%d %b\n' 65 "$( printf '\\0%o\n' 65 )"
65 A
\0ddd
在这里,我们首先使用 格式将 65 转换为八进制数,然后在另一个使用 的%o
格式中使用该结果。printf
%b