これは、あなたが提供するデータで機能します:
#include <stdio.h>
int main(void)
{
char lsm[2];
long unsigned int address;
int objsize;
while (scanf("%1s %lx,%d\n", lsm, &address, &objsize) == 3)
printf("%s %9lx %d\n", lsm, address, objsize);
return 0;
}
複数の変更があります。最も単純で重要でないのは、 からfscanf()
への変更scanf()
です。それは私の便宜のためです。
重要な変更の 1 つは、 の型がlsm
1char
文字から 2 文字の配列になったことです。次に、フォーマット文字列は%1s
1 文字 (および NUL '\0'
) を文字列に読み込みますが、先頭の空白もスキップします (これは非常に重要です)。
もう 1 つの変更は、条件内での== 3
代わりの使用!= EOF
です。何か問題が発生した場合scanf()
は、成功した一致の数を返します。文字を読み取ることができたが、その後に続いたのは 16 進数ではなかったとします。1 を返します (EOF ではありません)。さらに、16 進数に一致するものが見つかるまで、反復ごとに 1 を返します。期待する値の数を常にテストしてください。
出力形式は、%9lx
. 私は 64 ビット システムでテストしていたので、9 桁の 16 進数は正常に変換されます。の 1 つの問題scanf()
は、変換でオーバーフローが発生した場合の動作が未定義であることです。
出力:
S 600aa0 1
I 4005b6 5
I 4005bb 5
I 4005c0 5
S 7ff000398 8
なぜ得た結果が得られたのですか?
最初の変換でスペースが に読み込まれましたが、16 進数へのlsm
変換に失敗したS
ため、次のサイクルに取り残されました。そのため、残りのガベージがアドレスとオブジェクト サイズの列に出力されました。2 番目の反復は を読み取りS
、最後の行までデータと同期していました。フォーマットの最後の改行 (フォーマット文字列の他の空白と同様) は空白を消費します。これが、先頭の空白にもかかわらず最後の行が機能した理由です。