Program Club

C의 printf 형식 문자열에 % c와 % s가 모두있는 이유는 무엇입니까?

proclub 2020. 10. 30. 21:16
반응형

C의 printf 형식 문자열에 % c와 % s가 모두있는 이유는 무엇입니까?


왜 C의 printf 형식 문자열에 %c%s?

%c단일 문자를 %s나타내고 null로 끝나는 문자열 나타내는 것을 알고 있지만 문자열 표현만으로는 충분하지 않습니까?


아마도 널로 끝나는 문자열과 문자를 구별하기 위해서 일 것입니다. 방금 가졌다 %s면 모든 단일 문자도 null로 끝나야합니다.

char c = 'a';

위의 경우 cnull로 종료되어야합니다. 이것은 내 가정입니다 :)


%sa 0(또는 '\0', 같은 것)에 도달 할 때까지 문자를 인쇄합니다 .

당신은 단지이있는 경우 char x;, 그것을 인쇄 printf("%s", &x);- 당신은 주소를 제공해야 할 것 때문에 %s예상하는char* -로, 예상치 못한 결과를 얻을 것이다 &x + 1힘이 될 수 없습니다 0.

따라서 널로 끝나지 않는 한 (매우 비효율적) 단일 문자를 인쇄 할 수 없습니다.

편집 : 다른 사람들이 지적했듯이 둘은 var args 매개 변수에서 다른 것을 기대합니다-하나는 포인터이고 다른 하나는 단일 문자입니다. 그러나 그 차이는 다소 분명합니다.


단일 문자가 null로 종료되어야한다고 다른 사람들이 언급 한 문제는 실제 문제가 아닙니다. 이는 형식에 정밀도를 제공하여 처리 할 수 ​​있습니다 %.1s.

내 관점에서 더 중요한 것은 %s어떤 형태로든 하나 또는 여러 문자에 대한 포인터를 제공해야한다는 것입니다. 즉, rvalue (계산 된 표현식, 함수 반환 등)를 인쇄하거나 변수를 등록 할 수 없습니다.

편집 : 나는이 답변에 대한 반응에 정말 화가 났으므로 아마도 이것을 삭제할 것입니다. 이것은 가치가 없습니다. 사람들은 질문을 읽지도 않고 질문의 전문성을 인식하는 방법을 알지 못해도 이에 대해 반응하는 것 같습니다.

이 명확하게하려면 : 나는 당신이 선호해야한다는 말을하지 않는 %.1s이상 %c. %c대체 할 수없는 이유 는 다른 답이 말하는 척하는 것과 다를 뿐이다 . 이 다른 답변은 기술적으로 잘못되었습니다. Null 종료는 %s.


printf 함수는 가변적 인 수의 인수가 있음을 의미하는 가변 함수입니다. 함수 (printf)가 호출되기 전에 인수가 스택에 푸시됩니다. printf 함수가 스택을 사용하려면 스택에있는 내용에 대한 정보를 알아야하며 형식 문자열이 해당 용도로 사용됩니다.

예 :

printf( "%c", ch );    tells the function the argument 'ch' 
                       is to be interpreted as a character and sizeof(char)

이므로

printf( "%s", s );   tells the function the argument 's' is a pointer 
                     to a null terminated string sizeof(char*)

C에서는 런타임 동안 유형 검사가 없기 때문에 'ch'와 's'를 구별하는 것과 같이 다른 방법으로 스택 내용을 결정하는 printf 함수 내에서 불가능합니다.


%s 널을 찾을 때까지 모든 문자를 인쇄합니다 (변수를 포인터로 처리).

%c 한 문자 만 인쇄합니다 (변수를 문자 코드로 처리)

%s문자가 포인터처럼 취급 될 것이기 때문에 문자를 사용 하는 것은 작동하지 않습니다. 그런 다음 null을 찾을 때까지 메모리에서 해당 위치 다음에 오는 모든 문자를 인쇄하려고합니다.

다른 방법으로 설명하기 위해 다른 답변에서 훔칩니다 .

를 사용하여 문자를 인쇄 %s하려면 다음을 사용하여 문자 주소를 적절하게 전달하고 null을 찾을 때까지 화면에 쓰레기를 쓰지 않도록 할 수 있습니다.

char c = 'c';
printf('%.1s', &c);

의 경우 %s값이 아닌 문자열의 주소를 제공해야합니다.

의 경우 %c문자 값을 제공합니다.

우리가 사용하는 경우 %s대신 %c, 어떻게 우리가 제공 할 수 '\0'있는 문자 이후를?


이 재미있는 질문에 또 다른 관점을 추가하고 싶습니다.

실제로 이것은 데이터 입력으로 귀결됩니다. 여기에서 문자에 대한 포인터를 제공하고 제공 할 수 있다는 답변을 보았습니다.

"%.1s"

이것은 사실 일 수 있습니다. 그러나 대답은 프로그래머에게 유연성을 제공하려는 C 디자이너의 노력과 실제로는 응용 프로그램의 풋 프린트를 줄이는 방법 (작지만)에 있습니다.

때로는 프로그래머가 일련의 if-else 문이나 switch-case를 실행하고 싶을 수도 있습니다. 여기서 단순히 상태에 따라 문자를 출력해야합니다. 이를 위해 문자를 하드 코딩하면 단일 문자가 32 비트 또는 64 비트 (64 비트 컴퓨터의 경우) 인 포인터에 비해 8 비트이므로 실제로 메모리에서 실제 공간을 덜 차지할 수 있습니다. 포인터는 메모리에서 더 많은 공간을 차지합니다.

실제 문자와 문자에 대한 포인터를 사용하여 크기를 줄이려면 printf 유형의 연산자 내에서이를 수행 할 수있는 두 가지 방법이 있습니다. 하나는 .1s를 키 오프하는 것이지만, 당신이 문자에 대한 포인터 또는 문자열에 대한 포인터 (문자 배열)에 비해 문자 유형을 진정으로 제공하고 있다는 것을 루틴이 어떻게 확실히 알 수 있습니까? 이것이 그들이 "% c"를 사용하는 이유입니다.

재미있는 질문 :-)


C에는 서로 다른 유형을 처리하기 때문에 %c%s형식 지정자가 있습니다.

A char와 문자열은 밤과 1만큼 다릅니다.


% c는 정수 값인 char를 예상하고 인코딩 규칙에 따라 인쇄합니다.

% s는 char을 포함하는 메모리 위치에 대한 포인터예상하고 0 (null) 문자를 찾을 때까지 인코딩 규칙에 따라 해당 위치의 문자를 인쇄합니다.

따라서 두 가지 경우는 비슷해 보이지만 하나는 값으로 작업하고 다른 하나는 포인터로 작업하므로 공통점이 많지 않습니다. 하나는 특정 정수 값을 ascii char로 해석하는 명령이고, 다른 하나는 메모리 위치 char의 내용을 char로 반복하고 0 값이 나올 때까지 해석하는 것입니다.


printf("%.1s", &c)으로 실험을했습니다 printf("%c", c). 아래 코드를 사용하여 테스트하고 bash의 time유틸리티를 사용하여 실행 시간을 얻었습니다.

    #include<stdio.h>
    int main(){
        char c = 'a';
        int i;
        for(i = 0; i < 40000000; i++){
            //printf("%.1s", &c); get a result of 4.3s
            //printf("%c", c); get a result of 0.67s
        }
        return 0;
    }

그 결과를 사용하는 %c것이 %.1s. 따라서 % s는 % c의 작업을 수행 할 수 있지만 성능을 위해서는 % c가 여전히 필요합니다.


Since no one has provided an answer with ANY reference whatsoever, here is a printf specification from pubs.opengroup.com which is similar to the format definition from IBM

%c

The int argument shall be converted to an unsigned char, and the resulting byte shall be written.

%s

The argument shall be a pointer to an array of char. Bytes from the array shall be written up to (but not including) any terminating null byte. If the precision is specified, no more than that many bytes shall be written. If the precision is not specified or is greater than the size of the array, the application shall ensure that the array contains a null byte.

참고URL : https://stackoverflow.com/questions/10846024/why-does-cs-printf-format-string-have-both-c-and-s

반응형