2016-06-21 4 views
1

printfのフォーマット文字列を指定すると、期待される引数の数を返す標準のC/C++関数がありますか?例えば:printfの引数の数を確認する

num_printf_args("%d %s") == 2; 
num_printf_args("%.1f%%") == 1; 
num_printf_args("%*d") == 2; 

ちょうど形式文字列で%の数をカウントする第一の例ではなく、明らかではない第二及び第三のもので働く第一次近似であろう。

実際にprintfに渡された引数の数(およびそれらの型)が書式文字列と一致しない場合、コンパイル時にエラーが発生するので、gccはこれを行うことができます。

+0

ISO/IEC 9899にはこのような機能:1999(言語標準)。完全にはわからない:2011年、しかし私はそうは思わない。これはGCCによって実装された拡張機能です。 – DevSolar

+1

引数の型に関する情報がないと、なぜ便利なのでしょうか? –

+0

これは言語の一部ではなく、特定のgcc拡張です。 [gccの関数属性](https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html)の 'format'を参照してください。 – usr2564301

答えて

5

これを行う標準機能はありません。

しかし、実装が簡単です。

%の後に別の%がないことをカウントしてください。 %と計数されたものの1つ1つにつき1を追加した直後に*が続きます。

%の文字数をカウントするときは、重複を許可しないでください。 "%%% d"は1の値になります(0ではなく、確かに2または3ではありません)。

EDIT - user694733

から追加された次のコメントの下のテキストこれは、あなたが与えた3例の線に沿って、フォーマット文字列のために十分であろう。しかし、コメントでuser694733が指摘したように、これはすべての話ではありません。

一般的に、書式指定子はプロトタイプ%[flags][width][.precision][length]specifierに従います。上記のアプローチは出発点であり、flags、可能な*が指定子にあり、precision指定子には*がなく、lengthspecifierフィールドを見落とすフォーマット文字列に対して機能します。一般的な書式文字列とそれに応じて解析される文字列について、それらのすべてを考慮する必要があります。これを行う努力は、無効な書式文字列を検出する必要がある場合など、カウントが必要な頑健性に依存します。

+2

それは簡単ではありません。二重の '*'とフラグの場合も考慮する必要があります。例えば ​​'%+ *。* f'のようになります。基本的に完全なフォーマット文字列パーサーを実装する必要があります。 – user694733

+0

@ user694733 OPが与えた例については、私の応答で十分ですが、私は同意します - そうでない他の例/私は限界についてのコメントを追加し、まもなくやる必要がある他の事柄を追加します。 – Peter

2

私はあなたがこれを必要とする理由は、しかし、あなたの問題this way(この質問から受け入れ答え:Variadic macro trick)で解決される可能性がありますかわかりません。

コメントで示唆されているように、printfの呼び出しを最初に必要な引数の数を数えるマクロにラップし、何をしたいのかを進めることができます。ブログ記事から

コード:

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1) 
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N 

// to verify, run the preprocessor alone (g++ -E): 
VA_NUM_ARGS(x,y,z) 
+0

ええ、私は実際にこれと一緒に行った:http://stackoverflow.com/a/33349105/199554。 – Wim

関連する問題