0

次のコードは機能します。

unsigned int i1;unsigned int i2;
float *v1;float *v2;
sscanf("1 1 2.0 3.0","%u %u %f",&i1,&i2,v1,v2);
printf("%f",v1);

別の %f を追加すると、次は機能しません。コンパイルはできますが、bash が表示されます: [9612: 1 (255)] tcsetattr: デバイスの不適切な ioctl。

unsigned int i1;unsigned int i2;
float *v1;float *v2;
sscanf("1 1 2.0 3.0","%u %u %f %f",&i1,&i2,v1,v2);

どうして?!

4

1 に答える 1

2

質問が変わりました!

最初のコードは失敗するはずです。あなたは渡す必要があり、それは(a)アドレスではなく、(b)とにかくそれに対する変換仕様がないため &v1、渡す意味がありません。v2

で初期化されたポインターを渡していないため、最初のコードは失敗するはずです。また、フォーマット文字列によって初期化も使用もされていないためv1、渡す意味がありません。v2初期化されていないポインタを に渡すとsscanf()、未定義の動作が呼び出され、どのような応答も受け入れられます — 壊滅的な失敗 (ディスクを消去しますか?)、またはほぼ期待通りの無害な動作 (そのような無害な動作を期待する十分な根拠がないにもかかわらず)。同様のコメントがほとんどの関数に適用されます。初期化されていないポインターを渡さないでください。そうすることで何か良いことが起こることはめったにありません。

2 番目は、初期化されたアドレスを渡していないため失敗します。

修正コード 1:

unsigned int i1;
unsigned int i2;
float f1;
float *v1 = &f1;
if (sscanf("1 1 2.0 3.0", "%u %u %f", &i1, &i2, v1) == 3)
    printf("%f\n", *v1);

(未使用の変数v2は削除されました。)

代替案 1:

unsigned int i1;
unsigned int i2;
float v1;
if (sscanf("1 1 2.0 3.0", "%u %u %f", &i1, &i2, &v1) == 3)
    printf("%f\n", v1);

(ポインター変数はありません。)

修正コード 2:

unsigned int i1;
unsigned int i2;
float v1;  // Not pointer
float v2;  // Not pointer
if (sscanf("1 1 2.0 3.0", "%u %u %f %f", &i1, &i2, &v1, &v2) == 4)
    printf("%f %f\n", v1, v2);

または:

unsigned int i1;
unsigned int i2;
float f1;
float f2;
float *v1 = &v1;  // Initialized pointer
float *v2 = &v2;  // Initialized pointer
if (sscanf("1 1 2.0 3.0", "%u %u %f %f", &i1, &i2, v1, v2) == 4)
    printf("%f %f\n", f1, f2);  // Or *v1, *v2

ポインター変数のないバージョンの方が賢明だと思います。

変換が機能したことを確認するためのテストに注意してください。

于 2013-04-08T04:19:50.420 に答える