web-dev-qa-db-ja.com

sscanfによって読み取られた文字数を取得しますか?

文字列を解析しています(char*)そして私はsscanfを使用して、文字列からの数値を次のようにdoubleに解析しています。

// char* expression;
double value = 0;
sscanf(expression, "%lf", &value);

これはうまく機能しますが、それでも従来の方法で文字列を解析し続けたいと思います。新しいオフセットから手動解析を再開できるように、sscanfによって解析された文字数を知る必要があります。

明らかに、最も簡単な方法は、sscanfが解析する文字数を何らかの方法で計算することですが、それを行う簡単な方法がない場合は、am代替の二重解析オプションを利用できます。ただし、現在sscanfを使用しているのは、高速でシンプルで読みやすいためです。いずれにせよ、doubleを評価し、その後も解析を続ける方法が必要です。

30
Alexis King

フォーマット指定子_%n_を使用して、sscanf()に追加の_int *_引数を指定できます。

_int pos;
sscanf(expression, "%lf%n", &value, &pos);
_

C99標準のフォーマット指定子nの説明:

入力は消費されません。 対応する引数は、このfscanf関数の呼び出しによってこれまでに入力ストリームから読み取られた文字数が書き込まれる符号付き整数へのポインターでなければなりません。 _%n_ディレクティブの実行は、fscanf関数の実行の完了時に返される割り当てカウントをインクリメントしません。引数は変換されませんが、1つが消費されます。変換仕様に割り当て抑制文字またはフィールド幅が含まれている場合、動作は定義されていません。

常にsscanf()の戻り値をチェックして、割り当てが行われたことを確認してください。後続のコードは、値が変更されていない変数を誤って処理しません。

_/* Number of assignments made is returned,
   which in this case must be 1. */
if (1 == sscanf(expression, "%lf%n", &value, &pos))
{
    /* Use 'value' and 'pos'. */
}
_
44
hmjd
int i, j, k;
char s[20];

if (sscanf(somevar, "%d %19s %d%n", &i, s, &j, &k) != 3)
    ...something went wrong...

変数kには、jに格納されている整数の終わりがスキャンされた時点までの文字数が含まれています。

%nは、成功した変換ではカウントされないことに注意してください。必要に応じて、フォーマット文字列で%nを数回使用できます。

3