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.