次のコードがあります
int myInt;
sscanf(str, "%d=%s", &myInt, str);
これは有効ですか?ループしている場合、これを行うより良い方法はありますか?
%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, <) == 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つの方法は、strtol
etcを使用することです。これは、数値が>制限の場合、typeおよびsetの値をMAX値に設定するように定義されていますerrno = ERANGE
。CStdLib.html#strtol
私の推測では、ソース文字列が常に >= 結果文字列になるように見え、それが決定論的で指定された結果を引き起こすように見えるため、これは通常うまくいくと思います。
しかし、私はまだそれをしません。ライブラリ関数には通常restrict
、最適化とプリフェッチを可能にするために修飾されたパラメーターがあります。
コンパイラを誘惑しないでください。