printf / scanf: 入出力の基本と罠

ユーザーと対話するための関数。特にscanfには致命的な罠がある。

書式指定子
%d や %s など、データの型を指定する記号。
バッファオーバーフロー
用意した領域を超えて書き込み、メモリを破壊すること。
標準入力
キーボードからの入力のこと。

詳細解説

宅配便の住所 (Delivery Address)

scanf の `&` は「届け先の住所」です。 変数 `age` は「年齢という値」ですが、`&age` は「メモリ上の住所(番地)」です。 宅配業者(scanf)に荷物(入力値)を届けてもらうには、単に「20歳」と言うのではなく、「東京都...の住所」を教える必要があります。だから `&`(住所演算子)が必要なのです。

printf: 整形の美学

ただ数字を出すだけでなく、「5桁で揃える」「小数点以下2桁にする」といった整形(フォーマット)は、表データを出力する際に必須の技術です。

scanf: ポインタへの入り口

scanf を使うとき、変数の前に & をつける必要があります。これは「変数の値」ではなく「変数の住所(アドレス)」を渡すためです。住所を伝えないと、郵便屋さんが荷物を届けられないのと同じで、 scanf 関数も変数に値を書き込めないのです。

printf

Common Format Specifiers
// printf の書式指定
int a = 123;
double b = 3.14159;
// 整形(テーブル表示などで必須)
printf("|%5d|\n", a); // "| 123|" (5桁右詰め)
printf("|%-5d|\n", a); // "|123 |" (5桁左詰め)
printf("|%05d|\n", a); // "|00123|" (ゼロ埋め)
// 小数点以下の桁数
printf("%.2f\n", b); // "3.14" (四捨五入される)

scanf

Basic Usage
// scanf の基本
int age;
// 重要: 変数の前に & (アンパサンド) をつける!
scanf("%d", &age);
// なぜ & が必要なのか?
// 「値」ではなく「住所(アドレス)」を渡さないと、
// 関数が外の変数に書き込めないから。

実践テクニック

scanfの危険性

実務では、裸の scanf("%s") は絶対に使ってはいけません。入力文字数の制限がないため、長い文字列を入力されるとメモリ破壊(バッファオーバーフロー)が起き、セキュリティホールになります。

Safe Input Patterns
// ❌ 危険なコード
char name[10];
scanf("%s", name); // 10文字以上入力するとクラッシュ(バッファオーバーフロー)
// ✅ 安全策1: 文字数制限
scanf("%9s", name); // 9文字までしか読まない
// ✅ 安全策2: fgetsを使う(現場の推奨)
fgets(name, sizeof(name), stdin);

演習課題

課題1: 名簿作成
年齢(整数)と身長(実数)を入力させ、以下のようにきれいに整形して表示してください。
Age: 20
Height: 170.5
Output:
| Age | Height |
|  20 | 170.50 |

合格ライン

変数の値を右詰め・左詰めで表示できる
scanfで & が必要な理由を説明できる
scanf("%s") が危険な理由を知っている