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
0개 이상의 바이트를 포함하는 문자열일 수 있습니다. 하나 이상의 바이트를 포함하는 경우첫 번째 바이트를 써야 합니다.그리고 추가 바이트는 무시되어야 합니다. 인수가 빈 문자열인 경우 아무것도 기록되지 않거나 널 바이트가 기록되는지 여부가 지정되지 않습니다.매개변수 피연산자는 문자열로 처리되어야 합니다.해당 변환 지정자가
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