scanf
scanf(スキャンエフ)は、Cstdio.h
で
ユーザーからの
このファミリーの
形式
stdio.h
int scanf(const char *format, ...);
printf とformat
は、それに
#include <stdio.h>
int main(void)
{
int x; /* スキャン結果 を格納 する変数 。 */
printf("x = ? "); /* 入力 を促 すプロンプト。 */
/* スキャンと結果 の確認 。 */
if (scanf("%d", &x) == 1) {
printf("スキャン結果 = %d\n", x);
}
else {
printf("スキャン失敗 \n");
}
return 0;
}
変換 指定
scanf の
% [代入 抑止 ][最大 フィールド幅 ][長 さ修飾 子 ]変換 指定 子
代入 抑止
フラグ | |
---|---|
* | フォーマットに |
char c;
scanf("%*c%c", &c);
というコードがあり、 "ab"という
長 さ修飾 子
hh | C99 | |
h | ||
l(エル) | wchar_t についてはC95 | |
ll(エルエル) | C99 | |
j | C99 | |
z | C99 | |
t | C99 | |
L |
変換 指定 子
d,i | 10 |
|
u | 10 |
|
o | 8 |
|
x,X | 16 |
|
e,E | ||
f,F | ||
g,G | ||
a,A | C99 | |
c | ||
s | ||
p | ポインタの |
|
n | ||
% | '%'の |
|
[...] | [ ] それ |
[ ] は
char str[256];
scanf("%[abc]", str);
というコードがあり、
char str[256];
scanf("%[^abc]", str);
という
コード例
ソース:
#include <stdio.h>
#include <limits.h>
int main(void)
{
int n1, n2, nadd, nsub, nmul, ndiv, nmod;
printf("1つ目 の入力 数値 :");
if (scanf("%d", &n1) != 1) {
puts("スキャン失敗 ");
return -1;
}
printf("2つ目 の入力 数値 :");
if (scanf("%d", &n2) != 1) {
puts("スキャン失敗 ");
return -1;
}
if (n2 == 0) {
/* ゼロ除算 防止 のチェック。 */
puts("2つ目 の数値 は非 ゼロを入力 してください");
return -1;
}
if (n1 == INT_MIN && n2 == -1) {
/* 除算 と剰余 のオーバーフローエラー防止 のチェック。 */
puts("オーバーフローしない数値 の組 み合 わせを入力 してください");
return -1;
}
nadd = n1 + n2;
nsub = n1 - n2;
nmul = n1 * n2;
ndiv = n1 / n2;
nmod = n1 % n2;
printf("%d + %d = %d\n", n1, n2, nadd);
printf("%d - %d = %d\n", n1, n2, nsub);
printf("%d * %d = %d\n", n1, n2, nmul);
printf("%d / %d = %d + %d / %d\n", n1, n2, ndiv, nmod, n2);
return 0;
}
1つ目 の入力 数値 :60
2つ目 の入力 数値 :21
60 + 21 = 81
60 - 21 = 39
60 * 21 = 1260
60 / 21 = 2 + 18 / 21
関連 する関数
fscanf
int fscanf(FILE *fp, const char *format, ...);
fscanf は
sscanf
int sscanf(const char *str, const char *format, ...);
sscanf は
scanfの問題 点 と回避 方法
scanf は
改行 文字 の取 り扱 い
char a, b, c;
scanf("%c", &a);
scanf("%c", &b);
scanf("%c", &c);
とした
scanf("%c", &a);
scanf(" %c", &b);
scanf(" %c", &c);
のように
scanf("%c%*c", &a);
scanf("%c%*c", &b);
scanf("%c%*c", &c);
という
空白 、タブの読 み飛 ばし
scanf は
char a[20];
scanf("%s", a);
という
scanf("%[^\n]", a);
という
scanf("%[^\n]%*c", a);
という
バッファオーバーラン
char a[20];
scanf("%s", a);
というコードがあった
char a[20];
scanf("%19s", a);
とすることで、aには
char a[20];
scanf("%19s%*[^\n]", a);
これは19バイト
さらに
char a[20];
scanf("%19s%*[^\n]%*c", a);
となるが、この
char a[20];
scanf("%19s%*[^\n]", a);
getchar();
のように
char a[20];
scanf("%19[^\n]%*[^\n]", a);
getchar();
となる。
バージョン8.0 (2005)
異常 な入力 が行 われた時 の処理
scanf
int i;
scanf("%d", &i);
としたコードがあった
int i;
while(1) {
scanf("%d", &i);
if (i == 1) {
break;
}
}
というようなコードで
int i;
while(1) {
if (scanf("%d", &i) != 1) {
scanf("%*s");
if (feof(stdin)) {
/* エラー処理 */
}
continue;
}
if (i == 1) {
break;
}
}
この
int i, j;
scanf("%d %d", &i, &j);
のようなコードで、
int i, j;
if (scanf("%d %d", &i, &j) != 2) {
エラー処理
}
という
char a[20];
int i, j;
scanf("%19[^\n]%*[^\n]", a);
getchar();
if (sscanf(a, "%d %d", &i, &j) != 2) {
エラー処理
}
脚注
- ^ “[
迷信 ] scanf ではバッファオーバーランを防 げない”. C/C++迷信 集 .株式会社 きじねこ. 2010年 2月 28日 閲覧 。 “書式 指定 が不適切 なために発生 する脆弱 性 であって、scanf の問題 ではありません。”