1

次のコードがあります

int myInt;
sscanf(str, "%d=%s", &myInt, str);

これは有効ですか?ループしている場合、これを行うより良い方法はありますか?

4

2 に答える 2

3

%n変換仕様を利用できます-これまでに読み取られた文字。int*パラメータが必要ですCStdLib.html#fscanf

注目に値する。標準では、約%n

  • 入力は消費されません。
  • 対応する引数は、符号付き整数へのポインタでなければなりません。
    • これまでに読み取った文字数が書き込まれます。
  • 完了時に返される割り当てカウントをインクリメントしません。
  • 割り当て抑制文字またはフィールド幅が含まれている場合、動作は定義されていません。

参照。ISO / IEC 9899:1999§7.19.6.2

コンセプトとして:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int n;
    char *str = "12345=blabla 1313=blah "
                "333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee";
    char buf[15];
    int lt;

   /*                        +----- limit read to buffer length -1
                             |                +--- store read length here
                             |                |                        */
    while (sscanf(str, "%d=%14s%n", &n, buf, &lt) == 2) {
        fprintf(stdout,                   
            ":: '%s' :: \n"
            "Num: %d\n"
            "Str: %s\n"
            "Tot: %d bytes\n\n",
            str,
            n, buf,
            lt);
         str += lt;
    }

    return 0;
}

(長すぎる%s入力はループを中断します)のようなものを与える必要があります:

:: '12345=blabla 1313=blah 333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 12345
Str: blabla
Tot: 12 bytes

:: ' 1313=blah 333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 1313
Str: blah
Tot: 10 bytes

:: ' 333=hello 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 333
Str: hello
Tot: 10 bytes

:: ' 343=goodbyeeeeeeeeeeeeeeeeeeeeeeeeeeee' :: 
Num: 343
Str: goodbyeeeeeeee
Tot: 19 bytes

バッファよりも長く入力を処理したい方法はたくさんあります。つまり、eofかどうかを確認し、str再割り当てしない場合は再割り当てします。長さ=strなどのバッファーから始めます。

数値>INT_MAXまたは<INT_MINは未定義の動作()であることに注意してください。「%d」指定を使用すると、(通常は)INT_MAXまたはINT_MINにそれぞれ切り捨てられますか?

すなわち:

"1234533333333333333=blabla", read by "%d%s" =>

Num: 2147483647
Str: blabla
Tot: 26 bytes consumed

これに取り組む1つの方法は、strtoletcを使用することです。これは、数値が>制限の場合、typeおよびsetの値をMAX値に設定するように定義されていますerrno = ERANGECStdLib.html#strtol

于 2012-04-16T09:18:11.197 に答える
3

私の推測では、ソース文字列が常に >= 結果文字列になるように見え、それが決定論的で指定された結果を引き起こすように見えるため、これは通常うまくいくと思います。

しかし、私はまだそれをしません。ライブラリ関数には通常restrict、最適化とプリフェッチを可能にするために修飾されたパラメーターがあります。

コンパイラを誘惑しないでください。

于 2012-04-16T08:11:23.913 に答える