scanfは一般的に使うべきではないというが、なぜか検証してみる。
Red Hat Linux release 8.0 gcc v3.2
scanfはscan formatted関数の略称。
scanfでの空白文字とは、ブランク、タブ、改行、復帰、垂直タブ、改ページである。
scanfの"%d"は改行の前の数字だけ取得する。入力ストリームには改行コードが残る。getsはその改行コードを入力としてしまう。
int main(int argc, char *argv[]) {
int input;
char string[5];
scanf("%d", &input);
gets(string);
printf("%s", string);
return 0;
}
scanfは数字以外に出くわすと処理を終了し、かつそれら不必要なデータを
入力ストリームに放置する。以下がサンプルソースコード。
int main(int argc, char *argv[]) {
int input1;
int input2;
char string [2];
/* ここで数字以外を入力してみる。*/
scanf("%d", &input1); /* 数字ではないので処理を終了 */
scanf("%d", &input2); /* 数字ではないので処理を終了 */
scanf("%s", string); /* 文字なので個々でscanする */
printf("%s", string);
}
下記の"%s"の場合は、入力ストリームにゴミを残していない。
int main(int argc, char * argv[]) {
char string1 [5];
char string2 [5];
scanf("%s", string1);
gets(string2);
printf("string1=%d", strlen(string1));
printf("string2=%d", strlen(string2));
return 0;
}
$ ./a.out
aa
string1=2string2=0
つまり%dと%sでは、挙動が異なる。
scanf("%s", string1)で、分かるようにscanfはバッファ量を決めることができない。
つまりどんな大きなデータも詰め込める。つまりオーババッファフローが可能である。
scanfではなくfgetsで標準入力からデータを取得し、sscanf(string scan function)で
取得したデータを利用する。