Skip to main content

第5回 入力チェック

✅ 第5回 入力エラーを調べよう

4桁を何度も入力できるようになりました。

しかし、プレイヤーが必ず正しい形式で入力するとは限りません。

12
12345
1b35
abcd
1123

ゲームで使えない入力は、判定処理へ進む前に止める必要があります。


1.今回確認する入力エラー

次の3種類を確認します。

エラー番号 内容
0 エラーなし
1 文字数が4ではない
2 数字以外の文字が含まれている
3 同じ数字が重複している

入力を調べ、エラー番号を返す関数を作ります。

int CheckAnswerError(char input[]);
  • 引数:プレイヤーが入力した文字列
  • 戻り値:エラー番号

2.ここでC言語:戻り値で結果を返す

return 1;

returnは、関数を終了し、呼び出し元へ値を返します。

int error = CheckAnswerError(input);

関数が1を返した場合、errorへ1が入ります。

💡 エラーを見つけた時点でreturnすれば、その後のチェックは実行されません。


3.文字数が4か確認する

if (strlen(input) != 4)
{
    return 1;
}

!=は「等しくない」という意味です。

入力文字数 ≠ 4
        ↓
桁数エラー1を返す

4.数字以外の文字がないか確認する

数字の文字かどうかを調べるには、isdigitを使います。

#include <ctype.h>
isdigit(input[i])
  • 数字の文字なら0以外を返す
  • 数字の文字でなければ0を返す

4文字を1文字ずつ確認します。

int i;

for (i = 0; i < 4; i++)
{
    if (!isdigit((unsigned char)input[i]))
    {
        return 2;
    }
}

!は条件を反対にする

!isdigit(...)

これは、「数字ではない」という意味です。

💡 (unsigned char)は、isdigitへ安全に文字を渡すための型変換です。今回は数字と英字程度の入力でも動きますが、関数を正しく使う形として付けています。


5.数字の重複を確認する

入力が1123の場合、1が重複しています。

各文字を、後ろにある文字と比較します。 (自分自身以外の全部と気合で比べるよ)

全部で6通り?
input[0]と比較  input[1]、input[2]、input[3]
input[1]と比較  input[2]、input[3]
input[2]と比較  input[3]

二重のfor文を使います。

int i;
int j;

for (i = 0; i < 4; i++)
{
    for (j = i + 1; j < 4; j++)
    {
        if (input[i] == input[j])
        {
            return 3;
        }
    }
}

内側のji + 1から始めることで、次を避けています。

  • 自分自身との比較
  • すでに調べた組合せの再比較

6.入力エラーチェック関数

#include <ctype.h>
#include <string.h>

int CheckAnswerError(char input[])
{
    int i;
    int j;

    if (strlen(input) != 4)
    {
        return 1;
    }

    for (i = 0; i < 4; i++)
    {
        if (!isdigit((unsigned char)input[i]))
        {
            return 2;
        }
    }

    for (i = 0; i < 4; i++)
    {
        for (j = i + 1; j < 4; j++)
        {
            if (input[i] == input[j])
            {
                return 3;
            }
        }
    }

    return 0;
}

最後までエラーが見つからなかった場合は、0を返します。


7.戻り値を表示して動作確認する

入力ループを次のように変更します。

while (1)
{
    int error;

    printf("予想した4桁の数字を入力:");
    scanf("%254s", input);

    error = CheckAnswerError(input);
    printf("エラー番号:%d\n", error);
}

次のような結果になれば成功です。

入力例 戻り値 理由
12 1 4文字ではない
12345 1 4文字ではない
1b35 2 数字以外が含まれる
abcd 2 数字以外が含まれる
1123 3 1が重複している
3456 0 エラーなし

8.エラー内容を表示する

エラー番号だけでは、プレイヤーには意味が分かりません。

void ShowInputError(int error)
{
    if (error == 1)
    {
        printf("4桁で入力してください。\n");
    }
    else if (error == 2)
    {
        printf("0~9の数字だけを入力してください。\n");
    }
    else if (error == 3)
    {
        printf("同じ数字を2回使わないでください。\n");
    }
}

入力ループでは、次のように使えます。

error = CheckAnswerError(input);

if (error != 0)
{
    ShowInputError(error);
}
else
{
    printf("使用できる入力です。\n");
}

9.疑似言語との対応

・error ← 入力エラーを調べる(input)

▲ error ≠ 0
│ ・入力エラーを表示する
├────────────────
│ ・次の判定処理へ進む
▼

C言語では次の部分です。

error = CheckAnswerError(input);

if (error != 0)
{
    ShowInputError(error);
}
else
{
    /* HIT・BLOW判定へ進む */
}

🏁 今回のまとめ

  • 入力は必ずルールどおりとは限らない
  • エラー番号を戻り値として返せる
  • strlenで文字数を確認する
  • isdigitで数字の文字か確認する
  • 二重ループで数字の重複を調べる
  • エラーを見つけた時点でreturnする
  • エラーがなければ0を返す

次回は、入力エラーがなかった文字列について、HITとBLOWを数えます。