printf()
とで印刷できることはわかっていますputs()
。printf()
また、変数を補間してフォーマットを行うことができることもわかります。
puts()
のプリミティブバージョンにすぎませんprintf()
。printf()
文字列補間なしで可能な限りすべて使用する必要がありますか?
puts
はより単純ですprintf
が、前者は自動的に改行を追加することに注意してください。それが希望しない場合はfputs
、文字列をstdoutするか、を使用できますprintf
。
(これは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
fputs
同じことがvsにも当てはまりますfprintf
(ただしfputs
、改行は追加されません)。
フォーマットに加えて、成功または失敗したputs
場合は負でない整数を返します。EOF
whileprintf
は、出力された文字数を返します (末尾の null は含みません)。
単純なケースでは、コンパイラは への呼び出しを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
。
int puts(const char *s);
puts()は、文字列 s と末尾の改行を stdout に書き込みます。
int printf(const char *format, ...);
関数printf()は、後続の引数を出力用に変換する方法を指定するフォーマット文字列の制御下で、出力を stdout に書き込みます。
この機会にドキュメントを読んでいただきたいと思います。
私の経験では、フォーマット文字列に関係なく、 printf()
より多くのコードを取り込みます。puts()
フォーマットが必要ない場合は、使用しませんprintf
。ただし、fwrite
tostdout
は よりもはるかに高速に動作しputs
ます。
static const char my_text[] = "Using fwrite.\n";
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout);
注: コメントごとに、'\0' は整数定数です。正しい表現はsizeof(char)
、コメントで示されているとおりです。
そうprintf
です、のより強力なバージョンと考えることができますputs
。、、、などのフォーマット指定子を使用して、出力用に変数をフォーマットprintf
する機能を提供します。%s
%d
%lf
printf() 関数は文字列と変数の両方を画面に出力するために使用されますが、puts() 関数は文字列のみを画面に出力することのみを許可します。
と を比較するputs()
とprintf()
、メモリ消費量はほぼ同じですが、 にputs()
比べて時間がかかりますprintf()
。