フリーキーズ | 独学プログラミング

C言語の標準入出力を理解しよう!初心者でもわかるprintf、scanf関数の使い方

最終更新日
リンドくん

リンドくん

たなべ先生、C言語でプログラムを作ってみようと思うんですが、画面に文字を表示したり、キーボードから入力する方法がわからなくて...

たなべ

たなべ

いい質問だね!その機能を「標準入出力」と言うんだ。
C言語の基本中の基本だから、しっかり理解しておくと良いよ。今日はそれについて詳しく説明していくね。

C言語における標準入出力とは

プログラミングにおいて最も基本的で重要な機能の一つが「標準入出力」です。
これは簡単に言えば、プログラムがユーザーとやり取りするための仕組みです。

C言語では主に printf() 関数と scanf() 関数を使って実現します。

標準入出力を理解することは、プログラミング学習において非常に重要です。なぜなら、どんなプログラムも何らかの形でデータを入力し、結果を出力するからです。
例えば、計算機能を作るときも、ユーザーが数値を入力し、計算結果が画面に表示されなければ意味がありませんよね。

C言語の標準入出力は、基本的な使い方を押さえておけば様々なプログラムの基礎として活用できます。

printf関数でデータを出力する

リンドくん

リンドくん

画面に「Hello, World!」と表示させるにはどうすればいいんですか?

たなべ

たなべ

それには printf() 関数を使うんだよ!
これはC言語で最もよく使われる出力関数なんだ。

printf関数の基本

printf() 関数は、データを画面(標準出力)に表示するための関数です。
使い方はとても簡単です。

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

このコードを実行すると、画面に「Hello, World!」と表示されます。ここで重要なポイントがいくつかあります。

  • include文 = stdio.h というヘッダファイルを読み込んでいます。このファイルには標準入出力関数の定義が含まれています。
  • \n = これは改行を意味する特殊な文字(エスケープシーケンス)です。これがないと次の出力が同じ行に続いてしまいます。

変数の値を表示する

単純なメッセージだけでなく、変数の値も表示できます。
これには「フォーマット指定子」と呼ばれる特殊な記号を使います。

#include <stdio.h>

int main() {
    int age = 36;
    float height = 182.0;
    
    printf("年齢: %d歳\n", age);
    printf("身長: %.1fcm\n", height);
    
    return 0;
}

このプログラムでは以下のようにフォーマット指定子を使っています。

  • %d = 整数値(int型)を表示するためのフォーマット指定子
  • %f = 浮動小数点数(float型)を表示するためのフォーマット指定子
  • %.1f = 小数点以下1桁まで表示する指定

よく使われるフォーマット指定子には以下のようなものがあります。

  • %d: 整数(int)
  • %f: 浮動小数点数(float)
  • %c: 文字(char)
  • %s: 文字列(string)
  • %x: 16進数
  • %%: %記号そのもの

複数の値を一度に表示する

printf() 関数は、一つの命令で複数の値を表示することもできます。

#include <stdio.h>

int main() {
    int a = 10;
    int b = 20;
    int sum = a + b;
    
    printf("%d + %d = %d\n", a, b, sum);
    
    return 0;
}

これを実行すると「10 + 20 = 30」と表示されます。
複数の値を表示する場合は、フォーマット指定子の順番と変数の順番を一致させる必要があります。

scanf関数でユーザー入力を受け取る

リンドくん

リンドくん

ユーザーが何か入力できるようにするにはどうしたらいいですか?

たなべ

たなべ

それには scanf() 関数を使うんだ。
ただ、扱いにはちょっとした注意が必要だよ。

scanf関数の基本

scanf() 関数は、ユーザーからの入力を受け取るための関数です。
printf() と同様にフォーマット指定子を使いますが、少し使い方が異なります。

#include <stdio.h>

int main() {
    int number;
    
    printf("好きな数字を入力してください: ");
    scanf("%d", &number);  // アドレス演算子&に注意
    
    printf("あなたの選んだ数字は %d です。\n", number);
    
    return 0;
}

重要なポイントは以下です。

  • &演算子 = 変数の前に & を付ける必要があります(これはその変数のメモリアドレスを指定するためのものです)。
  • フォーマット指定子 = 入力する値の型に合わせたフォーマット指定子を使います(printf() と同じものが使えます)。

scanf_sを使う場合

リンドくん

リンドくん

Visual Studioでコードを書いていたら、scanf関数を使ったとき「安全でない可能性がある」というエラーメッセージが出てきました...

たなべ

たなべ

あぁ、それはVisual Studioの安全機能だね。
Microsoftは代わりにscanf_sという関数を使うことを推奨しているんだよ。

Visual Studioでプログラミングをしている方は、次のようなエラーメッセージを見たことがあるかもしれません。

'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

これはMicrosoftがセキュリティ上の理由から、従来のscanf()関数の代わりにscanf_s()を使うことを推奨しているためです。
scanf_s()scanf()のより安全なバージョンで、バッファオーバーフローを防ぐ機能が追加されています。

scanf_s()の使い方は基本的にscanf()と同じですが、文字列を読み込む場合は配列のサイズも指定する必要があります。

#include <stdio.h>

int main() {
    int age;
    char name[50];
    
    printf("お名前を入力してください: ");
    scanf_s("%s", name, (unsigned)sizeof(name));  // 配列のサイズを指定
    
    printf("年齢を入力してください: ");
    scanf_s("%d", &age);
    
    printf("こんにちは、%sさん。%d歳ですね。\n", name, age);
    
    return 0;
}

このエラーに対処する方法は2つあります。

  1. scanf_s()を使用する: 上記のように、より安全な関数を使います。
  2. _CRT_SECURE_NO_WARNINGSマクロを定義する: プロジェクトのプリプロセッサ定義に追加するか、ソースコードの先頭に以下を追加します。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

ただし、scanf_s()はMicrosoft固有の拡張機能であり、C言語の標準ではありません。そのため、異なるコンパイラ環境で実行する可能性がある場合は、移植性に注意が必要です。
学習目的であれば、警告を無視するか、_CRT_SECURE_NO_WARNINGSマクロを使用するのも一つの選択肢です。

複数の値を入力する

複数の値を一度に入力することもできます。

#include <stdio.h>

int main() {
    int a, b;
    
    printf("2つの整数を入力してください(スペースで区切る): ");
    scanf("%d %d", &a, &b);
    
    int sum = a + b;
    printf("合計: %d\n", sum);
    
    return 0;
}

このプログラムでは、ユーザーが「5 7」のように入力すると、a に5、b に7が代入され、その合計12が表示されます。

scanf関数を使う際の注意点

scanf() 関数は便利ですが、いくつか注意点があります。

  1. 入力バッファの問題: 文字入力と数値入力を混ぜると予期せぬ動作をすることがあります。
  2. バッファオーバーフロー: 文字列入力時に配列のサイズを超える入力をされると、セキュリティ上の問題が発生します。
  3. &演算子の忘れ: 変数の前に & を付け忘れると、プログラムが正しく動作しません(文字列配列の場合は例外です)。

特に初心者の方がつまずきやすいのが、文字と数値の入力を混ぜる場合です。
以下に適切な対処法を示します。

#include <stdio.h>

int main() {
    int age;
    char name[50];  // 最大49文字の名前を格納できる配列
    
    printf("お名前を入力してください: ");
    scanf("%s", name);  // 文字列の場合は&は不要
    
    printf("年齢を入力してください: ");
    scanf("%d", &age);
    
    printf("こんにちは、%sさん。%d歳ですね。\n", name, age);
    
    return 0;
}

標準入出力を使った基本的なプログラム例

リンドくん

リンドくん

実際にprintf関数とscanf関数を使ったプログラム例をもう少し見せてもらえますか?

たなべ

たなべ

もちろん!実践的な例を通して理解を深めていこう。
まずは簡単な計算機プログラムを見てみよう。

簡単な計算機プログラム

#include <stdio.h>

int main() {
    int a, b;
    char operation;
    
    printf("簡単な計算機\n");
    printf("2つの整数と演算子(+, -, *, /)を入力してください(例: 5 + 3): ");
    scanf("%d %c %d", &a, &operation, &b);
    
    switch(operation) {
        case '+':
            printf("%d + %d = %d\n", a, b, a + b);
            break;
        case '-':
            printf("%d - %d = %d\n", a, b, a - b);
            break;
        case '*':
            printf("%d * %d = %d\n", a, b, a * b);
            break;
        case '/':
            if(b != 0) {
                printf("%d / %d = %d(商), %d(余り)\n", a, b, a / b, a % b);
            } else {
                printf("0で割ることはできません。\n");
            }
            break;
        default:
            printf("無効な演算子です。\n");
    }
    
    return 0;
}

このプログラムは以下のような流れで実行されます。

  1. ユーザーから2つの整数と演算子を入力してもらう
  2. 入力された演算子に基づいて計算を行う
  3. 結果を表示

文字列の入力と処理

より複雑な例として、ユーザーから文字列を入力して処理するプログラムも見てみましょう。

#include <stdio.h>
#include <string.h>  // 文字列処理関数を使うため

int main() {
    char name[50];
    int choice;
    
    printf("お名前を入力してください: ");
    scanf("%s", name);
    
    printf("\nこんにちは、%sさん!以下のオプションから選んでください:\n", name);
    printf("1. 名前の長さを表示\n");
    printf("2. 名前を大文字で表示\n");
    printf("3. 名前を10回繰り返して表示\n");
    printf("選択(1-3): ");
    scanf("%d", &choice);
    
    switch(choice) {
        case 1:
            printf("%sさんの名前の長さは %lu 文字です。\n", name, strlen(name));
            break;
        case 2:
            printf("大文字の名前: ");
            for(int i = 0; name[i]; i++) {
                // 小文字ならば大文字に変換
                if(name[i] >= 'a' && name[i] <= 'z') {
                    printf("%c", name[i] - 32);  // ASCIIコードで変換
                } else {
                    printf("%c", name[i]);
                }
            }
            printf("\n");
            break;
        case 3:
            for(int i = 1; i <= 10; i++) {
                printf("%d. %s\n", i, name);
            }
            break;
        default:
            printf("無効な選択です。\n");
    }
    
    return 0;
}

このプログラムでは以下のような流れで実行されます。

  1. ユーザーに名前を入力してもらう
  2. メニューから処理を選択してもらう
  3. 選択に応じて、名前の長さの表示、大文字変換、繰り返し表示のいずれかを行う

まとめ

リンドくん

リンドくん

なるほど!標準入出力の基本が分かってきました。
でも、これからもっと複雑なプログラムを作るにはどうしたらいいですか?

たなべ

たなべ

基本をマスターしたら、次は応用だね。ファイル入出力や、より安全な入力方法、そして実用的なプログラムへと進んでいくといいよ。
何よりも実際に手を動かして練習することが大切だよ。

C言語の標準入出力は、プログラミングの基本中の基本です。printf() 関数と scanf() 関数を使いこなせるようになると、単純なプログラムから複雑なアプリケーションまで、ユーザーとのインタラクションを実装できるようになります。

標準入出力の理解は、C言語プログラミングの土台となります。
これをしっかりと習得すれば、より複雑で実用的なプログラムへと段階的に進むことができるでしょう。

最後に、プログラミングは実践が何よりも大切です。この記事で学んだことを活かして、様々なプログラムを実際に書いてみてください。
エラーが出ても挫折せず、デバッグを通じて学ぶことも重要な学習プロセスです。

関連するコンテンツ