scanf("%d",&rows)
の代わりに使用scanf("%s",input)
これにより、intに変換しなくても、stdinから整数値を直接取得できます。
ユーザーが数字以外の文字を含む文字列を入力した場合は、次の文字列の前にstdinをクリーンアップする必要がありますscanf("%d",&rows)
。
コードは次のようになります。
#include <stdio.h>
#include <stdlib.h>
int clean_stdin()
{
while (getchar()!='\n');
return 1;
}
int main(void)
{
int rows =0;
char c;
do
{
printf("\nEnter an integer from 1 to 23: ");
} while (((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin()) || rows<1 || rows>23);
return 0;
}
説明
1)
scanf("%d%c", &rows, &c)
これは、ユーザー入力から整数を期待し、それに近い数字以外の文字を期待することを意味します。
例1:ユーザーが入力aaddk
とENTER
、scanfは0を返します。大文字と小文字は区別されません。
例2:ユーザーが入力45
とENTER
、scanfは2を返します(2つの要素がキャプされます)。ここ%d
にキャッピングが45
あり、%c
キャッピング\n
例3:ユーザーが入力45aaadd
とENTER
、scanfは2を返します(2つの要素がキャプされます)。ここ%d
にキャッピングが45
あり、%c
キャッピングa
2)
(scanf("%d%c", &rows, &c)!=2 || c!='\n')
例1:この条件はTRUE
、scanfが0
(!=2
)
例2の場合:この条件はFALSE
、scanfが戻り2
、c == '\n'
例3の場合:この条件はTRUE
、scanfが戻り2
、c == 'a' (!='\n')
3)
((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
clean_stdin()
関数が常にTRUE
戻るためです1
例1の場合:(scanf("%d%c", &rows, &c)!=2 || c!='\n')
はTRUE
、後の条件を&&
チェックする必要があるため、clean_stdin()
が実行され、条件全体はTRUE
例2の場合:これ(scanf("%d%c", &rows, &c)!=2 || c!='\n')
はFALSE
、後の条件&&
がチェックされないため(結果が条件全体になるためFALSE
)、clean_stdin()
実行されず、条件全体がFALSE
例3の場合:(scanf("%d%c", &rows, &c)!=2 || c!='\n')
はTRUE
、後の条件を&&
チェックする必要があるため、clean_stdin()
が実行され、条件全体はTRUE
したがってclean_stdin()
、ユーザーが数字以外の文字を含む文字列を入力した場合にのみ実行されることに注意してください。
そして、この状態は、ユーザーが他に何も入力しない場合にのみ((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
返されますFALSE
integer
そして、条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
がFALSE
であり、integer
がとの間に1
ある23
場合、while
ループは中断されます。そうでない場合、while
ループは続行されます。