Cで非常に簡単なコード行を書く場合:
printf("Ascii char for %d is %c\n",65,65);
A
ASCII値65が文字に対応しているため印刷されますA
。しかし、シェルで同じコードを使用してコマンドを書くと、
printf "Ascii char for %d is %c\n" 65 65
出力はで表示されますAscii char for 65 is 6
。 Cと同じ出力が期待され、論理的に与えられたASCIIコードに対応する文字も印刷する必要があります。
このような状況では、なぜ異なる動作をしますか?
答え1
文字列を受け入れ、%c
文字列の最初の文字を印刷します。あなたの例のように文字列があれば65
印刷されます6
。
これは次のために発生します。printf
このユーティリティのPOSIX仕様:
変換指定子の引数は、
c
ゼロ個以上のバイトを含む文字列です。 1 つ以上のバイトを含む場合最初のバイトを書く必要があります。そして追加のバイトは無視する必要があります。引数が空の文字列の場合、何も書き込まれないかヌルバイトが書き込まれるかは指定されません。パラメータオペランドは文字列として扱われる必要があります。対応する変換指定子が
b
、c
またはs
[...]の場合
これは意味する議論形式は、%c
C(小さい正の整数がaに変換される場合char
)とシェル(同じ整数がまだ複数の数字を含む文字列の場合)で解釈されます。しかし、フォーマット自体は同じことを行い、バイトを文字として出力します。
しかし:
$ printf '%d %b\n' 65 '\0101'
65 A
101は8進数で65です。%b
POSIXでは、次のように指定されています
b
以下のように、追加の変換指定子文字をサポートする必要があります。引数は、<backslash>
エスケープシーケンスを含むことができる文字列として処理する必要があります。 [...]
\0ddd
、ここでは、ddd
8進数で指定された値を持つバイトに変換する必要がある0、1、2、または3つの8進数です。
これは追加標準 C では変換指定子が使用できないためです。ただし、POSIXシェルには型変数がないため、シェルに必要です。
返品:
$ printf '%d %b\n' 65 "$( printf '\\0%o\n' 65 )"
65 A
\0ddd
ここでは、まず形式を使用して65を8進数に変換し、%o
その結果を別の形式で使用します。printf
%b