-2

printf のすべての機能を発見しようとしていますが、これを試しました:

printf("Test:%+*0d", 10, 20);

印刷する

テスト:%+100d

最初にフラグを使用し+、次に幅*とフラグを再利用しました0

なぜこの出力を作るのですか?わざと悪いprintf()意味で使ったのになんで100と表示されるのかな?

4

3 に答える 3

2

これは、コンパイラに構文上のナンセンスを提供しているため、必要なことを自由に行うことができるためです。関連する読み取り、未定義の動作

警告を有効にしてコードをコンパイルすると、次のようなメッセージが表示されます

警告: 形式 [-Wformat=] に不明な変換タイプの文字 '0' があります
printf("Test:%+*0d", 10, 20);
^

正確には、ステートメントは次のいずれかである必要があります。

  • printf("Test:%+*.0d", 10, 20); // note the '.'

    ここで、は精度0として使用されます

    関連、C11章 §7.21.6.1 を引用 (強調鉱山)

    、、、、、および変換で表示される最小桁数、 、、、、および変換で小数点文字の後に表示される桁数、および変換で表示さdれる有効桁数の最大値を指定するオプションの精度。and変換、または s 変換で書き込まれる最大バイト数。精度は、ピリオド ( ) の後にアスタリスク(後述) またはオプションの 10 進整数が続く形式を取ります。iouxXaAeEfFgG.*期間のみが指定されている場合、精度はゼロと見なされます。精度が他の変換指定子と共に表示される場合、動作は未定義です。

  • printf("Test:%+0*d", 10, 20);

    ここで、はフラグ0として使用されます。構文に従って、すべてのフラグは一緒に表示される必要があります。他の変換仕様エントリの前に、変換仕様のどこかにフラグを置いて、コンパイラが意図に従うことを期待することはできません。

    繰り返しますが、引用します(そして私の強調

    各変換仕様は、文字によって導入されます%。の後に%以下が順番に表示されます。

    • 0 個以上のフラグ(任意の順序で) [...]
    • オプションの最小フィールド幅[...]
    • オプションの精度[...]
    • オプションの長さ修飾子[...]
    • 変換指定子[.... ]
于 2016-11-13T14:58:52.553 に答える
1

フォーマットが正しくありませprintfん: フラグは幅指定子の前に置く必要があります。

*幅指定子として処理された後、長さ修飾子または変換指定子のprintfいずれかが必要であり、これらのいずれでもない場合、動作は未定義です。.0

あなたのライブラリの実装はprintf奇妙な*ことをします。それを実際の幅引数に置き換えることで処理しているようです...実装の副作用です。他の人は、プログラムを中止するなど、何か他のことをするかもしれません。このような形式エラーは、変換が続く場合に特に危険です%s

コードを次のように変更printf("Test:%+0*d", 10, 20);すると、期待される出力が生成されます。

Test:+000000020
于 2016-11-13T15:37:29.510 に答える