[C言語] scanf関数を使って配列に値を入力する方法を解説

C言語で配列に値を入力する際、scanf関数を使用することが一般的です。

配列の各要素に値を入力するためには、forループを用いてscanfを繰り返し呼び出します。

例えば、整数型の配列に値を入力する場合、scanf(\"%d\", &array[i])のように、各要素のアドレスを指定して値を格納します。

この方法により、ユーザーからの入力を効率的に配列に保存することができます。

この記事でわかること
  • 配列の宣言と初期化の方法
  • scanf関数を用いた配列への入力手法
  • 動的配列やファイルからの入力の実践例
  • 入力データのバリデーションとエラーチェック
  • scanf関数とfgets関数の違いと使い分け

目次から探す

配列に値を入力する方法

配列の宣言と初期化

C言語で配列を使用するには、まず配列を宣言し、必要に応じて初期化します。

配列の宣言は、データ型、配列名、そして配列のサイズを指定して行います。

以下に基本的な配列の宣言と初期化の例を示します。

#include <stdio.h>
int main() {
    // 整数型の配列を宣言し、初期化
    int numbers[5] = {0, 1, 2, 3, 4};
    // 配列の要素を表示
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

このコードでは、numbersという名前の整数型の配列を宣言し、5つの要素を初期化しています。

forループを使って、配列の各要素を表示しています。

scanf関数を使った配列への入力

scanf関数を使用して、ユーザーからの入力を配列に格納することができます。

以下に、scanfを用いて配列に値を入力する例を示します。

#include <stdio.h>
int main() {
    int numbers[5];
    // ユーザーからの入力を配列に格納
    printf("5つの整数を入力してください:\n");
    for (int i = 0; i < 5; i++) {
        scanf("%d", &numbers[i]);
    }
    // 入力された値を表示
    printf("入力された整数は:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

このプログラムでは、ユーザーに5つの整数を入力してもらい、それを配列numbersに格納しています。

scanf関数を使う際には、各要素のアドレスを指定するために&演算子を使用します。

ループを用いた複数値の入力

配列に複数の値を入力する際、forループを用いることで効率的に処理を行うことができます。

上記の例でも示したように、forループを使うことで、配列の各要素に順番に値を入力することが可能です。

以下に、ループを用いた配列への入力の例を示します。

#include <stdio.h>
int main() {
    int numbers[5];
    // ループを用いて配列に値を入力
    printf("5つの整数を入力してください:\n");
    for (int i = 0; i < 5; i++) {
        printf("numbers[%d] = ", i);
        scanf("%d", &numbers[i]);
    }
    // 入力された値を表示
    printf("入力された整数は:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

このプログラムでは、forループを用いて、配列numbersの各要素にユーザーからの入力を格納しています。

ループを使うことで、コードが簡潔になり、可読性が向上します。

入力時の注意点とエラーチェック

scanf関数を使用する際には、いくつかの注意点があります。

特に、入力の形式が期待通りでない場合や、配列のサイズを超える入力が行われた場合に注意が必要です。

  • 入力形式の確認: scanf関数は、入力が期待される形式でない場合、入力を停止します。

入力形式を確認するために、戻り値をチェックすることが重要です。

  • 配列のサイズを超えないようにする: 配列のサイズを超える入力を防ぐために、ループの条件を正しく設定することが必要です。

以下に、エラーチェックを行う例を示します。

#include <stdio.h>
int main() {
    int numbers[5];
    int result;
    printf("5つの整数を入力してください:\n");
    for (int i = 0; i < 5; i++) {
        printf("numbers[%d] = ", i);
        result = scanf("%d", &numbers[i]);
        if (result != 1) {
            printf("入力エラーが発生しました。整数を入力してください。\n");
            return 1; // エラー終了
        }
    }
    printf("入力された整数は:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

このプログラムでは、scanfの戻り値をチェックし、入力が正しく行われたかどうかを確認しています。

入力エラーが発生した場合には、エラーメッセージを表示し、プログラムを終了します。

これにより、予期しない入力によるプログラムの誤動作を防ぐことができます。

実践例:配列への入力プログラム

単純な整数配列への入力

整数配列にユーザーからの入力を受け付ける基本的なプログラムを作成します。

以下の例では、5つの整数を入力し、それを配列に格納して表示します。

#include <stdio.h>
int main() {
    int numbers[5];
    printf("5つの整数を入力してください:\n");
    for (int i = 0; i < 5; i++) {
        printf("numbers[%d] = ", i);
        scanf("%d", &numbers[i]);
    }
    printf("入力された整数は:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

このプログラムは、ユーザーに5つの整数を入力させ、それを配列numbersに格納します。

入力された整数は、最後に順番に表示されます。

文字列配列への入力

文字列を配列に入力する場合、scanf関数を使用することもできますが、fgets関数を使うとより安全です。

以下に、文字列配列への入力例を示します。

#include <stdio.h>
int main() {
    char strings[3][20]; // 3つの文字列を格納する配列
    printf("3つの文字列を入力してください:\n");
    for (int i = 0; i < 3; i++) {
        printf("strings[%d] = ", i);
        fgets(strings[i], 20, stdin);
    }
    printf("入力された文字列は:\n");
    for (int i = 0; i < 3; i++) {
        printf("%s", strings[i]);
    }
    return 0;
}

このプログラムでは、3つの文字列を入力し、それぞれを配列stringsに格納します。

fgets関数を使用することで、改行文字も含めて入力を受け取ることができます。

二次元配列への入力

二次元配列に値を入力する場合、ネストされたループを使用します。

以下に、2×3の二次元配列に整数を入力する例を示します。

#include <stdio.h>
int main() {
    int matrix[2][3];
    printf("2x3の行列に整数を入力してください:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            printf("matrix[%d][%d] = ", i, j);
            scanf("%d", &matrix[i][j]);
        }
    }
    printf("入力された行列は:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

このプログラムでは、2行3列の行列に整数を入力し、入力された行列を表示します。

ネストされたforループを使用して、各要素にアクセスしています。

入力値のバリデーション

入力値のバリデーションを行うことで、ユーザーが不正なデータを入力した場合に適切に対応できます。

以下に、整数入力のバリデーションを行う例を示します。

#include <stdio.h>
int main() {
    int numbers[5];
    int result;
    printf("5つの整数を入力してください:\n");
    for (int i = 0; i < 5; i++) {
        printf("numbers[%d] = ", i);
        result = scanf("%d", &numbers[i]);
        while (result != 1) {
            printf("無効な入力です。整数を入力してください。\n");
            // 入力バッファをクリア
            while (getchar() != '\n');
            printf("numbers[%d] = ", i);
            result = scanf("%d", &numbers[i]);
        }
    }
    printf("入力された整数は:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

このプログラムでは、scanfの戻り値をチェックし、整数が入力されるまで再入力を促します。

無効な入力があった場合、入力バッファをクリアして再度入力を受け付けるようにしています。

これにより、ユーザーが誤ったデータを入力した際のエラーを防ぐことができます。

応用例

動的配列への入力

動的配列を使用することで、実行時に必要なメモリを確保し、配列のサイズを柔軟に変更することができます。

以下に、malloc関数を用いて動的配列に入力する例を示します。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int n;
    printf("入力する整数の数を入力してください: ");
    scanf("%d", &n);
    // 動的にメモリを確保
    int *numbers = (int *)malloc(n * sizeof(int));
    if (numbers == NULL) {
        printf("メモリの確保に失敗しました。\n");
        return 1;
    }
    printf("%dつの整数を入力してください:\n", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &numbers[i]);
    }
    printf("入力された整数は:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", numbers[i]);
    }
    // メモリを解放
    free(numbers);
    return 0;
}

このプログラムでは、ユーザーが入力する整数の数に応じてメモリを動的に確保し、入力された整数を格納しています。

使用後はfree関数でメモリを解放します。

ファイルからの入力を配列に格納

ファイルからデータを読み取り、配列に格納することも可能です。

以下に、ファイルから整数を読み取って配列に格納する例を示します。

#include <stdio.h>
int main() {
    FILE *file = fopen("data.txt", "r");
    if (file == NULL) {
        printf("ファイルを開くことができませんでした。\n");
        return 1;
    }
    int numbers[100];
    int i = 0;
    // ファイルからデータを読み取る
    while (fscanf(file, "%d", &numbers[i]) != EOF && i < 100) {
        i++;
    }
    fclose(file);
    printf("ファイルから読み取った整数は:\n");
    for (int j = 0; j < i; j++) {
        printf("%d ", numbers[j]);
    }
    return 0;
}

このプログラムは、data.txtというファイルから整数を読み取り、配列numbersに格納します。

ファイルの終わりまで、または配列の最大サイズに達するまで読み取りを続けます。

scanf関数と他の入力関数の組み合わせ

scanf関数と他の入力関数を組み合わせることで、より柔軟な入力処理が可能になります。

以下に、scanffgetsを組み合わせた例を示します。

#include <stdio.h>
int main() {
    char buffer[100];
    int number;
    printf("整数を入力してください: ");
    scanf("%d", &number);
    // 改行文字を消費
    getchar();
    printf("文字列を入力してください: ");
    fgets(buffer, 100, stdin);
    printf("入力された整数: %d\n", number);
    printf("入力された文字列: %s", buffer);
    return 0;
}

このプログラムでは、scanfで整数を入力した後、getcharを使って改行文字を消費し、fgetsで文字列を入力しています。

これにより、入力の順序を保ちながら異なるデータ型を扱うことができます。

入力データのソートと表示

入力されたデータをソートして表示することで、データの整理が可能です。

以下に、バブルソートを用いて整数配列をソートする例を示します。

#include <stdio.h>
void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
int main() {
    int numbers[5];
    printf("5つの整数を入力してください:\n");
    for (int i = 0; i < 5; i++) {
        scanf("%d", &numbers[i]);
    }
    bubbleSort(numbers, 5);
    printf("ソートされた整数は:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}

このプログラムでは、ユーザーから入力された5つの整数をバブルソートで昇順に並べ替え、ソートされた結果を表示します。

バブルソートはシンプルなアルゴリズムで、学習目的に適しています。

よくある質問

scanf関数で入力が失敗するのはなぜ?

scanf関数で入力が失敗する主な原因は、入力データの形式が期待される形式と異なる場合です。

例えば、整数を期待しているのに文字列が入力された場合、scanfは入力を停止し、バッファに残ったデータが次の入力に影響を与えることがあります。

これを防ぐためには、scanfの戻り値をチェックし、入力が正しく行われたかを確認することが重要です。

また、入力バッファをクリアするためにgetcharを使用することも有効です。

配列のサイズを超える入力を防ぐには?

配列のサイズを超える入力を防ぐためには、入力ループの条件を正しく設定することが重要です。

例えば、配列のサイズを超えないように、ループの条件をi < 配列のサイズとすることで、配列の範囲内でのみ入力を受け付けることができます。

また、動的配列を使用する場合は、必要に応じてメモリを再確保することで、柔軟にサイズを調整することが可能です。

scanf関数とfgets関数の違いは?

scanf関数fgets関数は、どちらも入力を受け取るために使用されますが、動作が異なります。

scanfはフォーマット指定子を使用して特定のデータ型を直接読み取ることができ、入力データの形式が重要です。

一方、fgetsは文字列として入力を受け取り、改行文字も含めてバッファに格納します。

fgetsはバッファオーバーフローを防ぐために、最大読み取り文字数を指定できるため、安全性が高いです。

入力の種類や安全性の観点から、適切な関数を選択することが重要です。

まとめ

C言語における配列への入力方法は、scanf関数を用いた基本的な方法から、動的配列やファイル入力などの応用例まで多岐にわたります。

この記事では、配列への入力に関するさまざまな手法と注意点を解説しました。

これらの知識を活用し、より安全で効率的なプログラムを作成してみてください。

  • URLをコピーしました!
目次から探す