printfでの「%。* s」の意味は?


112

私はあるコードスニペットを得ました

printf("%.*s\n")

どういう%.*s意味ですか?


26
追加の引数がなければ、それは有効なprintf呼び出しではありません。
Andrew Marshall、

回答:


119

フォーマット文字列にハードコーディング*するのprintf()ではなく、アスタリスク()を使用して、幅指定子/精度をに渡すことができます。

void f(const char *str, int str_len)
{
  printf("%.*s\n", str_len, str);
}

3
str_len引数には型int(またはに昇格されるより狭い整数型)が必要であることに注意してくださいint。合格するバグだろうlongsize_tなど、
MM

9
このコードのありそうな目的は、特にで使用される場合%s、元の文字列のサブ文字列を出力することであることに言及する価値があります。この使用例でstrは、は元の文字列内のどこか(おそらく先頭)を指し、str_len印刷されるサブ文字列の長さを指定します。
Sonic Atom

2
長さを指定することで、たとえばストリームまたはファイルベースのソースから入力された文字列など、nullターミネーターのない文字列を印刷(またはsprintf)することができます。これは、単に印刷したかわいらしいものよりも、私が遭遇したユースケースの方がはるかに多い。
コンラッドB

23

詳細はこちら

整数値または*最小フィールド幅を指定します。結果には、必要に応じて、右寄せの場合は左側に、左寄せの場合は右側に、空白文字(デフォルト)が埋め込まれます。*が使用される場合、幅はint型の追加の引数によって指定されます。引数の値が負の場合、-フラグが指定され、フィールド幅は正になります。(注:これは最小の幅です。値が切り捨てられることはありません。)

.整数または*が後に続くか、どちらも変換の精度を指定しません。*が使用される場合、精度はint型の追加の引数によって指定されます。この引数の値が負の場合、無視されます。数値も*も使用されない場合、精度はゼロと見なされます。精度の正確な影響については、以下の表を参照してください。

したがって、両方の変換仕様を試すと

#include <stdio.h>

int main() {
    int precision = 8;
    int biggerPrecision = 16;
    const char *greetings = "Hello world";

    printf("|%.8s|\n", greetings);
    printf("|%.*s|\n", precision , greetings);
    printf("|%16s|\n", greetings);
    printf("|%*s|\n", biggerPrecision , greetings);

    return 0;
}

出力を取得します。

|Hello wo|
|Hello wo|
|     Hello world|
|     Hello world|

12

上記のコードは正しいとは思わないが、(このの説明によるとprintf().*手段は

幅はフォーマット文字列では指定されていませんが、フォーマットする必要がある引数の前の追加の整数値引数として指定されています。

つまり、引数として渡せる幅を持つ文字列です。


2
盗用の請求を回避できるように、URLの相互参照を追加しました。もちろん、正しい引用は「は…ではなく」ではなく「精度は…ではない」と述べています。
ジョナサンレフラー2015年

@MattMcNabbが指摘したように、そのページへのすべての参照は、その「ハイライトしなければならない整数値を」正確であるint(またはそのサブセット) -より直感的なような任意の整数値だけではなく、size_tまたはその可能な別名、のようなstd::string::size_type。参照先のページsize_tでサポートされている型指定子の1つとして言及されていることを考慮すると、これはさらに混乱します。
アントンサムソノフ2015

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