sscanf()
とその親戚からの戻り値を常にチェックしてください。
- コンパイラの警告を有効にしてください。優れたコンパイラは、次の問題について教えてくれます。
- 姓を読み上げたい場合は、
*
inを使用して割り当てを抑制しないでください。%*[0-9]
sscanf()
あなたの行はあなたが言及したデータ構造を使用していないことに注意してください。ただし、このサンプル コードは次のことを行います。
#include <stdio.h>
typedef struct who
{
char name[20];
char surname[20];
int age;
char gender[7];
} who;
int main(void)
{
const char *data[2] =
{
"Pebbles Flintstone4Female",
"Bam-Bam Rubble3Male",
};
const char *fmt[2] =
{
"%[^ ]%*[^1234567890]%d%s",
"%[^ ]%[^1234567890]%d%s",
};
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
who buff;
int n;
if ((n = sscanf(data[j], fmt[i], buff.name, buff.surname, &buff.age, buff.gender)) != 4)
printf("Oops: format \"%s\", n = %d: %s\n", fmt[i], n, data[j]);
else
printf("Format \"%s\": data %s: %s %s %d %s\n",
fmt[i], data[j], buff.name, buff.surname, buff.age, buff.gender);
}
}
return 0;
}
出力例:
Oops: format "%[^ ]%*[^1234567890]%d%s", n = 3: Pebbles Flintstone4Female
Oops: format "%[^ ]%*[^1234567890]%d%s", n = 3: Bam-Bam Rubble3Male
Format "%[^ ]%[^1234567890]%d%s": data Pebbles Flintstone4Female: Pebbles Flintstone 4 Female
Format "%[^ ]%[^1234567890]%d%s": data Bam-Bam Rubble3Male: Bam-Bam Rubble 3 Male
フォーマットの文字列リテラルでコンパイルするとsscanf()
、GCC は問題について警告します。
td.c: In function ‘main’:
td.c:23: warning: format ‘%d’ expects type ‘int *’, but argument 4 has type ‘char *’
td.c:23: warning: format ‘%s’ expects type ‘char *’, but argument 5 has type ‘int *’
td.c:23: warning: too many arguments for format
異なるフォーマット文字列を使用した上記のコードでは、その警告は表示されません。
フォーマット文字列も、バッファ オーバーフローを避けるために変更する必要があります。
"%19[^ ] %19[^0-9] %d %6s"