C에서 printf ()와 puts ()의 차이점은 무엇입니까?


176

printf()및로 인쇄 할 수 있다는 것을 알고 있습니다 puts(). printf()변수를 보간하고 서식을 지정할 수 있다는 것도 알 수 있습니다.

인가 puts()단지의 원시적 버전 printf(). printf()문자열 보간없이 가능한 모든 경우에 사용해야합니까 ?



47
puts 대신 printf를 사용하는 것에 대한 참고 사항 : 결코 printf(variable)문자열을 인쇄 하지 마십시오 . puts(variable)또는을 사용하십시오 printf("%s', variable). 변수 형식 문자열을 사용하면 보안 위험이 있습니다. 공격자가 변수를 작성할 수 있으면 형식 문자열을 사용하여 프로그램을 공격 할 수 있습니다.
Zan Lynx

답변:


141

puts보다 간단 printf하지만, 전자는 자동으로 줄 바꿈을 추가 것을 유의하십시오. 그것이 원하는 것이 아니라면 fputs문자열을 stdout하거나 사용할 수 있습니다 printf.


8
출력 문자열에 변수를 추가하기 위해 printf가 취하는 추가 인수를 언급하는 것도 중요하다고 생각합니다.
Erutan409

99

(이것은 Zan Lynx의 의견에서 지적되었지만 허용 된 답변에 언급되어 있지 않다는 점을 고려할 때 가치가 있다고 생각합니다).

사이의 근본적인 차이 puts(mystr);와는 printf(mystr);후자에 인수가로 해석이다 서식 문자열 . 문자열에 제어 문자 ( %)가 포함되지 않은 경우 결과는 종종 동일하지만 (추가 된 줄 바꿈 제외), 그에 의존 할 수없는 경우 ( mystr리터럴 대신 변수 인 경우 ) 사용 해서는 안됩니다 .

따라서 동적 문자열을 단일 인수로 전달하는 것은 일반적으로 위험하며 개념적으로 잘못 되었습니다 printf.

  char * myMessage;
  // ... myMessage gets assigned at runtime, unpredictable content
  printf(myMessage);  // <--- WRONG! (what if myMessage contains a '%' char?) 
  puts(myMessage);    // ok
  printf("%s\n",myMessage); // ok, equivalent to the previous, perhaps less efficient

fputsvs 에도 동일하게 적용 fprintf되지만 fputs개행을 추가하지는 않습니다.


어떤 방식으로 사용 printf()하면 효율성이 떨어 집니까? 런타임에? 컴파일 타임에?
franklin

10
printf형식 문자열을 구문 분석해야하기 때문에 런타임에 @franklin . 그러나 이것은 일반적으로 관련이 없습니다. 더욱이 현명한 컴파일러는 이것을 최적화하고 printf를 호출로 대체 할 수 있습니다puts
leonbloy

33

형식화 외에도 puts성공하거나 EOF실패 하면 음이 아닌 정수를 리턴합니다 . while printf은 인쇄 된 문자 수 를 반환합니다 (후미 널은 포함하지 않음).


16

간단한 경우, 컴파일러 개종자는 호출 printf()에 대한 호출에 puts().

예를 들어 다음 코드는 다음에 표시 할 어셈블리 코드로 컴파일됩니다.

#include <stdio.h>
main() {
    printf("Hello world!");
    return 0;
}
push rbp
mov rbp,rsp
mov edi,str.Helloworld!
call dword imp.puts
mov eax,0x0
pop rbp
ret

이 예에서는 GCC 버전 4.7.2를 사용하고로 소스를 컴파일했습니다 gcc -o hello hello.c.


9
그리고 stdout에 장소를 두는 새로운 라인은 어떻습니까?
zubergu

1
printf("Hello world!\n");실제로 gcc 는 그것을 번역해야합니다. 오래된 메시지이므로 직접 편집하겠습니다.
Rafael Almeida

2
C 코드를 컴파일 한 후 어셈블리 코드를 어떻게 읽었습니까?
Koray Tugay

3
@ KorayTugay : -save-tempsgcc에 대한 옵션은 않습니다
schaiba

gdb와 같은 도구를 사용하여 바이너리를 디스 어셈블 할 수도 있습니다.
Ivan Kaloyanov

10

마우스 오른쪽 단추로, printf보다 강력한 버전으로 간주 할 수있다 puts. printf하는 기능을 제공 포맷 등과 같은 출력하여 포맷 지정자 변수 %s, %d, %lf, 등 ...


10

내 경험 에 따르면 형식 문자열에 관계없이 printf()더 많은 코드를 puts()사용합니다.

서식이 필요하지 않으면을 사용하지 않습니다 printf. 그러나, fwrite에가 stdout많은 것보다 더 빨리 작동합니다 puts.

static const char my_text[] = "Using fwrite.\n";
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout);

참고 : 주석마다 '\ 0'은 정수 상수입니다. 올바른 표현은 sizeof(char)주석으로 표시된 것과 같아야합니다 .


2
"stdout에 fwrite는 넣는 것보다 훨씬 빠르게 작동합니다." -이유가 무엇일까요?
Antony Hatchkins 2016 년

6
@AntonyHatchkins 일반적으로 "많이"빠르지는 않습니다. 그러나 puts ()는 문자열에서 strlen () 호출을 수행해야하지만 fwrite ()로 크기를 알고 있으면 피할 수 있습니다. 이는 성능 차이에있어 실질적으로 유일한 기여자입니다.
Wiz

8
이 답변은 잘못되었습니다. '\0'유형 int이 있으므로 대부분의 시스템에서 인쇄 Using fwrit됩니다. 당신이 1 적은 바이트를 인쇄하려면, 단지 1을 사용하여 sizeof (char)여기에 의도 1. 보장 무엇 가능성이있는
브래들리 Garagan을

8
int puts(const char *s);

puts () 는 문자열 s와 후행 줄 바꿈을 stdout에 씁니다.

int printf(const char *format, ...);

printf () 함수 는 후속 인수가 출력을 위해 변환되는 방법을 지정하는 형식 문자열의 제어하에 출력을 stdout에 기록합니다.

이 기회를 이용하여 문서를 읽도록 요청할 것입니다.


5

printf () 함수는 문자열과 변수를 모두 화면에 인쇄하는 데 사용되며 puts () 함수는 문자열 만 화면에 인쇄 할 수 있습니다.


2

puts간단한 선택이며 끝에 새 줄을 추가 printf하고 서식이 지정된 문자열에서 출력을 씁니다.

설명서를 참조 puts 하고 위해 printf.

나는 printf이것이 전환 방법보다 더 일관성이 있기 때문에 사용하는 것이 좋습니다 . 예를 들어 디버깅을하는 경우 putsand 보다 모든 printfs를 검색하는 것이 덜 고통 스럽습니다 printf. 대부분의 경우 출력물에 변수를 출력하고 싶기 때문에 puts대부분 예제 코드에서 사용됩니다.


1

비교할 경우 puts()printf(), 자신의 메모리 소비가 거의 동일 할지라도, puts()에 비해 시간이 더 걸립니다 printf().


다른 사람들이 그로부터 배울 수 있도록 귀하의 답변에 설명을 추가하십시오-그 주장에 대한 믿을만한 출처가 있습니까? 아니면이 차이점을 설명해야 할 이유가 있습니까?
니코 하세
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.