C言語基礎|printf関数とscanf関数

printfで“見せる”、scanfで“受け取る”。C言語の入出力を、書式のしくみごとスッキリ理解しよう!

C言語でプログラムを作ると、必ず登場するのが printf と scanf です。
printf は「画面に表示する係」、scanf は「キーボードから読み取る係」です。

ただ、便利なぶん落とし穴もあります。
printf は変換指定子と型が合っていないと表示が崩れたり、scanf は読み取りに失敗しても気づかないまま処理を続けてしまったりします。
この記事では、書式(フォーマット)の構造戻り値チェックを軸に、表や図で丁寧に整理していきますね。

printf と scanf の役割まとめ

2つの関数の違い

関数目的入出力先戻り値代表的な使いどころ
printf書式付きで出力標準出力(画面)出力した文字数(エラー時は負の値)案内表示、結果表示、デバッグ出力
scanf書式付きで入力標準入力(キーボード)代入できた項目数(失敗時は0、入力不可でEOF)数値・文字列の読み取り

表の説明

  • printf は「何文字出したか」を返します。多くの場面では使いませんが、ログ確認やエラー検出に使えます。
  • scanf は「いくつ代入できたか」を返します。ここを確認しないと事故が起きやすいです。

サンプルプログラム

「テスト3科目の点数を入力 → 平均を計算 → 見やすく表示」するプログラム例です。
scanf の戻り値チェック、printf の幅と精度がまとめて学べます。

プロジェクト名:chap13-12-1 ソースファイル名:chap13-12-1.c

#include <stdio.h>

int main(void)
{
    int a, b, c;

    /* 入力を促す(日本語メッセージ) */
    printf("3科目の点数を入力してください(例:80 75 90):");

    /* scanfの戻り値で、3個の整数が読めたか確認する */
    if (scanf("%d %d %d", &a, &b, &c) != 3) {
        printf("入力エラー:半角数字を3つ入力してください。\n");
        return 1;
    }

    /* 平均を計算(小数も出したいのでdoubleにする) */
    double avg = (a + b + c) / 3.0;

    /* 表示を整える:幅をそろえて見やすくする */
    printf("\n入力された点数\n");
    printf("  国語:%4d\n", a);
    printf("  数学:%4d\n", b);
    printf("  英語:%4d\n", c);

    /* 小数点以下2桁で平均を表示 */
    printf("\n平均:%6.2f 点\n", avg);

    return 0;
}

実行例(イメージ)

  • 3科目の点数を入力してください(例:80 75 90):80 75 90
  • 入力された点数
    国語: 80
    数学: 75
    英語: 90
  • 平均: 81.67 点

printf の書式(命令の書式)

  • ヘッダ:#include <stdio.h>
  • 形式:int printf(const char * restrict format, ...);

変換指定の構造(図)

図の説明

  • % から始まる部分が「変換指定」です。
  • 幅は“最低何文字分の枠を取るか”、精度は“(小数なら)小数点以下何桁にするか”です。

フラグ(flag)

フラグは「表示の仕方」を微調整する部品です。

よく使うフラグ

フラグ意味例(イメージ)
-左づめにする123___
+正の値でも + を付ける+123
空白正の値の先頭に空白を置く_123
#代替形式(例:16進に0xを付けるなど)0x1a
0左側の空きを0で埋める000123

表の説明

  • 表を作るような表示では、幅と合わせて 0 や - が役立ちます。
  • 0 と - を同時に指定すると 0 は無効になります(左づめが優先されるイメージです)。

最小フィールド幅(minimum field width)

幅は「最低限の枠」です。小さければ空白で埋まり、大きければそのまま広がります。

図:幅のイメージ(%4d)

図の説明

  • 幅は「最低」なので、値が長い場合に切られることはありません。
  • “表の縦をそろえる”のに便利です。

精度(precision)

精度は変換指定子によって意味が変わります。

精度の意味(代表例)

変換指定子精度の意味
f小数点以下の桁数%.2f → 3.14
d, i, u, x など表示する数字の最小個数(足りないぶん0が付く)%.5d → 00042
s最大文字数(それ以上は表示しない)%.3s → Hel

表の説明

  • 小数表示なら f と精度がセットで頻出です。
  • 文字列 s の精度は「最大何文字まで表示するか」になります。

長さ修飾子(length modifier)

長さ修飾子は「引数の型の大きさ」を指定します。

よく使う長さ修飾子

修飾子意味printf例
hshort系%hd
llong系%ld
lllong long系%lld
zsize_t%zu
Llong double%Lf

表の説明

  • 型に合わない指定子は未定義動作の原因になります。
  • size_t は配列サイズなどでよく出るので %zu は覚えておくと安心です。

変換指定子(conversion specifier)

printf でよく使う指定子をまず押さえましょう。

printfでよく使う指定子

指定子代表的な型内容
d, iint符号付き10進
uunsigned int符号なし10進
x, Xunsigned int16進(小文字/大文字)
fdouble小数(小数点形式)
e, Edouble指数形式
g, Gdouble値に応じて f/e を自動選択
cint(文字)1文字
schar *文字列
pvoid *ポインタ
%なし% を表示

表の説明

  • 小数は基本 f を使うと分かりやすいです。
  • g は便利ですが、表示形式が値によって変わるので初心者のうちは注意です。

scanf の書式(命令の書式)

  • ヘッダ:#include <stdio.h>
  • 形式:int scanf(const char * restrict format, ...);

scanf は「変数に代入する」ので、変数のアドレスを渡す必要があります。

scanfのよくある指定子と引数

指定子読み取る型渡すもの
dint&変数scanf("%d", &x)
lfdouble&変数scanf("%lf", &a)
cchar&変数scanf(" %c", &ch)
schar配列配列名scanf("%s", name)

表の説明

  • 数値は基本 &変数 です。
  • 文字列は配列名を渡します(配列名が先頭要素へのポインタとして働くためです)。
  • c の前の空白(" %c")は、直前の改行などを読み飛ばしたいときによく使うテクニックです。

scanfの戻り値チェック(ここが超重要)

scanf は入力に失敗すると代入しません。つまり、変数に前の値が残ったままになることがあります。

図:scanfの戻り値の意味

戻り値 = 代入できた項目数

例:scanf("%d %d %d", &a, &b, &c)
- 3つ読めた → 3
- 途中で文字が混ざって読めない → 0 または 1 や 2(読めた数だけ)
- 入力が終わっている/読めない → EOF

図の説明

  • サンプルでは != 3 をチェックして、入力が不正なら即終了しています。
  • この習慣があるだけで、scanf絡みのバグがかなり減ります。

よくあるつまずき(やさしく回避)

printf/scanfの典型ミスと対策

ありがちミス何が起きる?対策
printf の指定子が型と不一致表示が崩れる、未定義動作型に合う指定子を使う
scanf で & を忘れる変な場所に書き込み、クラッシュの原因数値は必ず &変数
scanf の戻り値を見ない失敗に気づかず処理が進む戻り値を必ず比較する
文字入力で改行が邪魔すぐに改行を拾ってしまう" %c" のように空白で読み飛ばす

表の説明

  • scanf は便利ですが「失敗しやすい」ので、戻り値チェックと入力設計がセットです。