🇯🇵 日本語 | 🇺🇸 English
広告スペース

第5回 scanf ― キーボード入力を受け取る

C言語の scanf 関数でキーボードからの入力を変数に取り込む方法。& の意味、%lf の罠、よくあるバグを1つずつ理解しましょう。

📖 このページで覚えること
✅ 最低限ここだけ覚える
  • scanf("%d", &x); で入力を受け取る
  • & を絶対に忘れない
  • double は %lf(printfの%fと違う!)
  • 書式文字列に余計な文字を入れない
⭐ 余裕があれば読む
  • scanf の戻り値でエラーを検出
  • 空白・改行のスキップルール
  • 入力バッファ残りの問題と対処
  • 文字列入力は fgets のほうが安全
💪 初心者は1回で分からなくて普通
scanf は「&」と「%lf」の2点で初学者を痛めつけます。どちらも後のポインタの話まで続く概念なので、今は「ルール」として覚えてOK。
つまずきポイント
  1. & は変数の「住所」を渡す合図 ― 後のポインタで詳しく
  2. double の書式は %lf(scanfのみ、printfは %fでOK)
  3. 入力中にスペースやEnterを挟んでも、数値系の書式は勝手にスキップ
  4. 変な動き=書式文字列に余計なものがある or & 忘れ
💡 コツ: エラーが出たら9割は「&忘れ」か「%lf忘れ」。疑いは先にこの2点。

scanf の基本 ― printf の反対方向

printfが「画面に出す」なら、scanfは「キーボードから受け取る」。反対方向の関数です。
📤 printf(出力)
printf("%d\n", a);
// 変数 a の値を画面に出す
📥 scanf(入力)
scanf("%d", &a);
// キーボードから受け取った値を変数 a に格納

基本的な書き方

int a;
printf("aの値を入力: ");  // プロンプト表示
scanf("%d", &a);          // キーボード入力を受け取る
printf("aは %d です\n", a);
流れ: ① printf で「何を入れるか」を表示 → ② scanf で受け取る → ③ 受け取った値を使う。この3ステップが基本セット。

⚠️ なぜ & (アンパサンド) が必要か

scanf で最も重要なルールは変数名の前に & をつけること。これを忘れるとプログラムがクラッシュします。
🔴 & を忘れるとどうなるか
int a;
scanf("%d", a);    // ❌ & を忘れた
結果:
• コンパイル時に警告が出る(警告を真剣に読む習慣を)
• 実行するとほぼ確実に Segmentation fault(プログラム強制終了)
• 運が悪いと別のメモリ領域を書き換えて、遠く離れた場所でバグる

& の正体:変数の「住所」

変数 a には値が入っています。&a は「その変数が置かれているメモリ上のアドレス」を表します。
a = 「箱の中身」(値)
&a = 「箱の場所」(アドレス)

scanf は「どこに値を書き込むか」を教えてもらう必要がある。
だから箱の場所&a)を渡す。
💡 暗記ルール: scanf の変数には必ず &。printf には付けない(printfは値を読むだけだから)。詳しい仕組みは第29回 ポインタで。

例外:文字列(配列)の場合

char name[50];
scanf("%s", name);   // ← 配列名には & を付けない
理由: 配列名はそのままアドレス扱いになる特別ルールがあるため、& なしでOK。今は「配列だけ例外」と覚えておけば十分です。

🧩 %lf の謎 ― double を受け取るときの書式

scanf ではdouble型 は %lf。これは printf と違うルールで、よくハマります。
scanf の書式printf の書式
int%d%d
float%f%f
double%lf ⚠️%f(%lfでもOK)
char%c%c
文字列%s%s
🔴 よくあるミス: double に %f を使う
double b;
scanf("%f", &b);    // ❌ double には %lf が必要
結果: 入力した値が全く違う変な値になる。0.0 になったり、極端に大きな数になったり、未定義の挙動。コンパイラは -Wall をつければ警告してくれる。
覚え方: scanf で double → sd%lf( lは「long」の l )。scanfのときだけ気をつけろ。

scanf シミュレーター

下の入力欄に値を入れて Enter を押すと、scanfでどう変数に入るかを体験できます。
aの値を入力:
変数 a の値
未入力
printf("%d", a) の結果

よくある落とし穴

落とし穴① & 忘れ
scanf("%d", &a);
&を忘れるとクラッシュ
落とし穴② double に %f
scanf("%lf", &b);
scanfのdoubleは%lf
落とし穴③ 書式に余計な文字
scanf("%d\n", &a);\n不要
scanf("値を入力%d", &a); ← 文章NG
落とし穴④ 連続scanf
scanf後に残った改行でバグる可能性。特に %c と他の書式を混ぜたときに注意。

✅ 安全な書き方テンプレート

int a;
double b;

printf("整数を入力: ");
scanf("%d", &a);

printf("小数を入力: ");
scanf("%lf", &b);  // ← lf !

printf("a=%d, b=%f\n", a, b);

💡 応用: 戻り値をチェックする

scanf は「正しく読めた項目の数」を返します。不正入力の検出に使えます。
int a;
if (scanf("%d", &a) != 1) {
    printf("整数を入れてください\n");
    return 1;
}
本格的な入力処理では fgets + sscanf の方がエラー処理しやすい。詳しくは安全な文字列操作で。

自分で書いてみよう ― scanf

ブラウザシミュレータではscanfは入力ダイアログで代用されます。
scanf_demo.c
出力
「実行」を押してください...
💡 こんなことも試してみよう
広告スペース

関連する講座

入門編
第4回 printf
画面に値を表示するprintfと書式指定子。
発展編
ポインタの基礎
scanf で出てきた &(アドレス)の正体。
応用トピック
安全な文字列操作
scanf より安全な fgets / sscanf の使い方。
← 前の講座
第4回 printf
次の講座 →
第6回 確認問題(変数・printf)