Cのprintfで%(パーセント)記号をエスケープする方法は?


274

printfCで使用する場合、%記号をどのようにエスケープしますか?

printf("hello\%"); /* not like this */

回答:


421

次のようにダブル '%'をポストすることでエスケープできます: %%

あなたの例を使用して:

printf("hello%%");

'%'記号のエスケープはprintf専用です。もし、するなら:

char a[5];
strcpy(a, "%%");
printf("This is a's value: %s\n", a);

印刷されます: This is a's value: %%


8
「printf( "hello %%");」は正しい。しかし、それは私が思うエスケープではありません。printf( "hello \ 045");を使用します。
ライ江山

1
@パブロサンタクルス:この「エスケープ」方法%はに固有のprintfものですか?
Lazer

10
これは、エスケープシステムで非常に一般的なルールの特殊なケースであり、リテラルエスケープシンボルを取得するには、<エスケープシンボル> <エスケープシンボル>を使用します。
dmckee ---元モデレーターの子猫2010

12
ライ江山、これはうまくいきません。言語の\045一部であり、コンパイル時に変換されるコンパイル時エスケープです。はランタイム関数であるため、Cソースコードではなく、文字列のバイトを処理し、関数の一部である独自のエスケープシーケンスを持っています。つまり、は「言語内の言語」であり、と同じ結果になります。%printfprintfprintf("This is a's value: %s\n", a);printf("This is a's value: \045\0163\012", a);
Triang3l 2013年

5
また、これを行うことができます:printf("hello%c", '%');。ただし、%%別の引数を使用しないため、より優れています。
Triang3l 2013年

36

他の人が言ったように、%%は%をエスケープします。

ただし、これは絶対に行わないでください。

char c[100];
char *c2;
...
printf(c); /* OR */
printf(c2);

文字列を印刷する必要があるときはいつでも、常に、常に、常にそれを使用して印刷します

printf("%s", c)

埋め込まれた%が問題を引き起こすのを防ぐため[メモリ違反、segfaultなど]


警告は一般的に適切ですが、「これ」を実行したい状況があるかもしれません-あなたが提供する文字列がフォーマット文字列として解釈されることを知っている限り。
PP。

2
私は一度、別の解決策を思いつきました-バッファーを別のバッファーにコピーしてから、%記号を2倍にします。私は最終的にこのアイデアに出くわし、20-30行の関数を1行に置き換えました。心配しないで、私は当然のように頭をひどく殴った。
Graeme Perrow、

真ですが、フォーマット文字列を取得する99%の時間は引数をva_listとして取得するため、vprintfを使用する必要があることを忘れないでください。したがって、私は技術的に正しいです;)
Mikeage 2009

2
puts(c)を実行する方がはるかに簡単です。If
ウィリアムパーセル2009

1
putsは改行を追加します。多くの場合、それは望ましくない動作です。
Mikeage 2009

33

文字列にフォーマットがない場合は、puts(またはfputs)を使用できます。

puts("hello%");

文字列にフォーマットがある場合:

printf("%.2f%%", 53.2);

コメントに記載されてputsいる\nように、出力にa を追加し、追加fputsしません。


4
fprints()に直接言及するため、fputs()についても言及する価値があります。
Tim Post

1
putsはまた、[すでに持っている場合でも]改行を追加します。あなたがそれを望むなら、素晴らしい。それ以外の場合...
Mikeage 2009

@SinanÜnür:について思い出させてくれてありがとうputsputs文字列を出力することを考えたことがなく、すぐににジャンプしましたprintf。もう違います。
Lazer


7

Nitpick:関数の(および)ファミリの形式を指定する文字列で、を
実際にエスケープすることはありません。%printf()scanf()

(及び機能の)ファミリー、変換仕様を開始します。変換指定の規則の1つは、変換指定子としての(変換指定を開始したの直後に続く)により、変換された引数なしで文字が書き込まれることを示しています。%printf()scanf()%%'%'

文字列の内部には実際に2 '%'文字あります(エスケープ文字とは異なり"a\bc"、3つのnull以外の文字を含む"a%%b"文字列、4つのnull以外の文字を含む文字列です)。


2
技術的には、まだ「脱出中」です。特別なキャラクターには、その特別な意味を「エスケープ」して「キャラクターの性質」に戻す方法が必要です
新武蔵


4

このような:

printf("hello%%");
//-----------^^ inside printf, use two percent signs together

3

Cのバックスラッシュは、文字列内の文字をエスケープするために使用されます。文字列は%を特殊文字として認識しないため、エスケープは必要ありません。Printfは別の問題です。%%を使用して1つの%を印刷します。





2

単純に%2回使用できます。"%%"

例:

printf("You gave me 12.3 %% of profit");

1

ダブル '%'は ".Format(…)でも機能します。例(iDrawApertureMask == 87、fCornerRadMask == 0.05):( csCurrentLine.Format("\%ADD%2d%C,%6.4f*\%",iDrawApertureMask,fCornerRadMask) ; 文字列の内容)csCurrentLineの望ましい値と期待される値を提供します;"%ADD87C、0.0500 *% 」

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.