[C言語] 正しい値が入力されるまでscanfを繰り返す方法

C言語でユーザーからの入力を受け取る際、scanfを使用して正しい値が入力されるまで繰り返す方法があります。

これは、whileループやdo-whileループを用いて、scanfの返り値をチェックすることで実現できます。

例えば、整数が入力されるまで繰り返す場合、scanfが1を返すかどうかを確認し、正しい入力が得られるまでループを続けます。

この方法により、プログラムの堅牢性を向上させ、ユーザーの誤入力に対する耐性を持たせることができます。

この記事でわかること
  • whileループとdo-whileループを用いた入力処理の実装方法
  • 複数の異なるデータ型の入力を扱う方法
  • 特定の範囲内の数値を入力させる方法
  • 文字列入力の際のエラー処理の方法
  • scanfでの無限ループの原因と対策方法

目次から探す

正しい値が入力されるまで繰り返す方法

C言語でユーザーからの入力を受け取る際、正しい値が入力されるまで繰り返し入力を求める方法について解説します。

特に、whileループとdo-whileループを用いた実装方法を中心に説明します。

whileループを用いた実装

whileループを使用することで、条件が満たされるまで繰り返し処理を行うことができます。

以下に、整数が入力されるまで繰り返す例を示します。

#include <stdio.h>
int main() {
    int number;
    int result;
    // 正しい整数が入力されるまで繰り返す
    while (1) {
        printf("整数を入力してください: ");
        result = scanf("%d", &number);
        // 入力が正しいかどうかをチェック
        if (result == 1) {
            break; // 正しい入力があればループを抜ける
        } else {
            printf("無効な入力です。もう一度入力してください。\n");
            // 入力バッファをクリア
            while (getchar() != '\n');
        }
    }
    printf("入力された整数は: %d\n", number);
    return 0;
}
整数を入力してください: abc
無効な入力です。もう一度入力してください。
整数を入力してください: 123
入力された整数は: 123

この例では、scanf関数の戻り値をチェックすることで、入力が正しいかどうかを判断しています。

無効な入力があった場合、エラーメッセージを表示し、入力バッファをクリアして再度入力を求めます。

do-whileループを用いた実装

do-whileループは、少なくとも一度はループ内の処理を実行したい場合に便利です。

以下に、do-whileループを用いた実装例を示します。

#include <stdio.h>
int main() {
    int number;
    int result;
    // 正しい整数が入力されるまで繰り返す
    do {
        printf("整数を入力してください: ");
        result = scanf("%d", &number);
        // 入力が正しいかどうかをチェック
        if (result != 1) {
            printf("無効な入力です。もう一度入力してください。\n");
            // 入力バッファをクリア
            while (getchar() != '\n');
        }
    } while (result != 1);
    printf("入力された整数は: %d\n", number);
    return 0;
}
整数を入力してください: xyz
無効な入力です。もう一度入力してください。
整数を入力してください: 456
入力された整数は: 456

この例では、do-whileループを使用することで、最初の入力を必ず受け付け、その後の入力が正しいかどうかをチェックしています。

入力のバリデーションとエラーメッセージの表示

入力のバリデーションは、ユーザーが期待される形式でデータを入力しているかを確認するプロセスです。

scanf関数を使用する際、入力が期待される形式でない場合、エラーメッセージを表示して再入力を促すことが重要です。

  • 入力の確認: scanfの戻り値をチェックし、期待されるデータ型が入力されたかを確認します。
  • エラーメッセージの表示: 無効な入力があった場合、ユーザーに対して具体的なエラーメッセージを表示します。
  • 入力バッファのクリア: 無効な入力があった場合、getcharを用いて入力バッファをクリアし、次の入力を正しく受け付ける準備をします。

これらの手法を組み合わせることで、ユーザーにとって使いやすい入力インターフェースを提供することができます。

応用例

C言語での入力処理は、単純な整数入力にとどまらず、さまざまなデータ型や条件に応じた入力を扱うことができます。

ここでは、複数の異なるデータ型の入力、特定の範囲内の数値入力、そして文字列入力の際のエラー処理について解説します。

複数の異なるデータ型の入力を扱う

複数の異なるデータ型を一度に入力する場合、scanfを用いてそれぞれのデータ型に対応するフォーマット指定子を使用します。

以下に、整数と浮動小数点数を同時に入力する例を示します。

#include <stdio.h>
int main() {
    int integer;
    float decimal;
    int result;
    // 整数と浮動小数点数を入力
    while (1) {
        printf("整数と浮動小数点数を入力してください (例: 10 3.14): ");
        result = scanf("%d %f", &integer, &decimal);
        // 入力が正しいかどうかをチェック
        if (result == 2) {
            break; // 両方の入力が正しければループを抜ける
        } else {
            printf("無効な入力です。もう一度入力してください。\n");
            // 入力バッファをクリア
            while (getchar() != '\n');
        }
    }
    printf("入力された整数は: %d, 浮動小数点数は: %.2f\n", integer, decimal);
    return 0;
}
整数と浮動小数点数を入力してください (例: 10 3.14): 10 abc
無効な入力です。もう一度入力してください。
整数と浮動小数点数を入力してください (例: 10 3.14): 10 3.14
入力された整数は: 10, 浮動小数点数は: 3.14

この例では、整数と浮動小数点数の両方が正しく入力されるまで繰り返し入力を求めます。

特定の範囲内の数値を入力させる

特定の範囲内の数値を入力させる場合、入力後にその値が範囲内にあるかをチェックします。

以下に、1から100の範囲内の整数を入力させる例を示します。

#include <stdio.h>
int main() {
    int number;
    int result;
    // 1から100の範囲内の整数を入力
    while (1) {
        printf("1から100の範囲内の整数を入力してください: ");
        result = scanf("%d", &number);
        // 入力が正しいかどうかをチェック
        if (result == 1 && number >= 1 && number <= 100) {
            break; // 正しい範囲内の入力があればループを抜ける
        } else {
            printf("無効な入力です。もう一度入力してください。\n");
            // 入力バッファをクリア
            while (getchar() != '\n');
        }
    }
    printf("入力された整数は: %d\n", number);
    return 0;
}
1から100の範囲内の整数を入力してください: 150
無効な入力です。もう一度入力してください。
1から100の範囲内の整数を入力してください: 50
入力された整数は: 50

この例では、入力された整数が1から100の範囲内であることを確認し、範囲外の場合は再入力を求めます。

文字列入力の際のエラー処理

文字列入力では、scanfの代わりにfgetsを使用することで、スペースを含む文字列を扱うことができます。

以下に、文字列入力の際のエラー処理を行う例を示します。

#include <stdio.h>
#include <string.h>
int main() {
    char input[100];
    // 文字列を入力
    while (1) {
        printf("文字列を入力してください: ");
        if (fgets(input, sizeof(input), stdin) != NULL) {
            // 改行文字を取り除く
            input[strcspn(input, "\n")] = '\0';
            // 入力が空でないかをチェック
            if (strlen(input) > 0) {
                break; // 有効な入力があればループを抜ける
            } else {
                printf("無効な入力です。もう一度入力してください。\n");
            }
        }
    }
    printf("入力された文字列は: %s\n", input);
    return 0;
}
文字列を入力してください: 
無効な入力です。もう一度入力してください。
文字列を入力してください: Hello, World!
入力された文字列は: Hello, World!

この例では、fgetsを用いて文字列を入力し、入力が空でないことを確認しています。

空の入力があった場合、再入力を求めます。

よくある質問

scanfで無限ループに陥るのはなぜ?

scanfで無限ループに陥る主な原因は、入力が期待される形式と異なる場合に、入力バッファに不正なデータが残り続けることです。

例えば、整数を期待しているのに文字列が入力された場合、scanfは入力を処理できず、バッファに残ったデータを再度読み込もうとします。

このため、無限ループに陥ります。

これを防ぐためには、入力が失敗した際にバッファをクリアする必要があります。

入力バッファをクリアする方法は?

入力バッファをクリアするには、getcharを用いてバッファ内のデータを読み捨てる方法があります。

具体的には、while (getchar() != '\n');のようにループを用いて、改行文字が現れるまでバッファを読み続けることでクリアできます。

この方法を用いることで、次の入力を正しく受け付けることができます。

scanf以外の入力方法はあるのか?

scanf以外にも、C言語では入力を受け取る方法があります。

例えば、fgetsを使用することで、スペースを含む文字列を安全に入力することができます。

fgetsは、指定したバッファサイズまでの文字列を読み込み、改行文字を含むため、入力の境界を明確にすることができます。

また、getcharを用いて1文字ずつ入力を受け取る方法もあります。

まとめ

C言語での入力処理は、正しい値が入力されるまで繰り返し処理を行うことで、ユーザーにとって使いやすいインターフェースを提供できます。

whileループやdo-whileループを用いることで、さまざまなデータ型や条件に応じた入力を扱うことが可能です。

この記事を通じて、入力処理の基本から応用までを理解し、実際のプログラムに活用してみてください。

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