ここに、ユーザーが文字または0未満または23を超える整数を入力できないようにするCコードに関する小さな若いtyroの問題があります。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char *input;
char *iPtr;
int count = 0;
int rows;
printf("Enter an integer: ");
scanf("%s", input);
rows = strtol(input, &iPtr, 0);
while( *iPtr != '\0') // Check if any character has been inserted
{
printf("Enter an integer between 1 and 23: ");
scanf("%s", input);
}
while(0 < rows && rows < 24) // check if the user input is within the boundaries
{
printf("Select an integer from 1 to 23: ");
scanf("%s", input);
}
while (count != rows)
{
/* Do some stuff */
}
return 0;
}
私は途中でそれを作ったし、小さなプッシュアップは高く評価されます。
scanf("%d",&rows)
の代わりにscanf("%s",input)
を使用します
これにより、intに変換する必要なく、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)
これは、ユーザー入力から整数とそれに近い非数字文字を期待することを意味します。
Example1:ユーザーがaaddk
を入力してからENTER
を入力すると、scanfは0を返します。キャプションなし
Example2:ユーザーが45
を入力してからENTER
を入力すると、scanfは2を返します(2要素がキャッピングされます) )。ここで%d
は45
をキャッピングし、%c
は\n
をキャッピングしています
Example3:ユーザーが45aaadd
を入力してからENTER
を入力すると、scanfは2を返します(2つの要素がキャッピングされます) )。ここで%d
は45
をキャッピングし、%c
はa
をキャッピングしています
2)
(scanf("%d%c", &rows, &c)!=2 || c!='\n')
example1:では、 scanfは0
(!=2
)を返すため、この条件はTRUE
です
example2:では、scanfは2
およびc == '\n'
を返すため、この条件はFALSE
です。
example3:では、scanfは2
およびc == 'a' (!='\n')
を返すため、この条件はTRUE
です。
3)
((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
関数は常に1
を返すため、clean_stdin()
は常にTRUE
です。
example1:では、(scanf("%d%c", &rows, &c)!=2 || c!='\n')
はTRUE
なので、&&
の後の条件をチェックして、clean_stdin()
が実行され、条件全体はTRUE
です
example2の場合:(scanf("%d%c", &rows, &c)!=2 || c!='\n')
はFALSE
なので、&&
の後の条件はチェックされませんその結果は、条件全体がFALSE
になるため、clean_stdin()
は実行されず、条件全体はFALSE
です。
example3で:(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
がbetweenであり、1
と23
である場合、while
ループは中断し、そうでない場合はwhile
ループが継続します
_#include <stdio.h>
main()
{
char str[100];
int num;
while(1) {
printf("Enter a number: ");
scanf("%[^0-9]%d",str,&num);
printf("You entered the number %d\n",num);
}
return 0;
}
_
scanf()
の_%[^0-9]
_は、_0
_と_9
_の間にないものをすべて使い果たします。基本的には、数字以外の入力ストリームを消去し、str
に入れます。さて、非数字シーケンスの長さは100に制限されています。次の_%d
_は、入力ストリーム内の整数のみを選択し、num
に配置します。
1から23の間の整数を読み取る関数、または非整数の場合は0を返す関数を作成できます。
例えば.
int getInt()
{
int n = 0;
char buffer[128];
fgets(buffer,sizeof(buffer),stdin);
n = atoi(buffer);
return ( n > 23 || n < 1 ) ? 0 : n;
}
char check1[10], check2[10];
int foo;
do{
printf(">> ");
scanf(" %s", check1);
foo = strtol(check1, NULL, 10); // convert the string to decimal number
sprintf(check2, "%d", foo); // re-convert "foo" to string for comparison
} while (!(strcmp(check1, check2) == 0 && 0 < foo && foo < 24)); // repeat if the input is not number
入力が数値の場合、foo
を入力として使用できます。
ループ内でstrtol
への呼び出しを繰り返して、ユーザーに再試行を要求する必要があります。実際、whileの代わりにループをdo { ... } while(...);
にすると、同じ種類の繰り返しが2回繰り返されることはありません。
また、コードがループ内ではなくどこにあるかを確認できるようにコードをフォーマットする必要があります。
MOHAMED、あなたの答えは素晴らしく、本当に助けになりました。ここにコードを投稿しましたが、それはもう少し簡単だと思います:
#include <stdio.h>
int getPositive(void);
void clean_input(void);
int main(void) {
printf("%d\n",getPositive());
return 0;
}
int getPositive(void) {
int number;
char buffer; // Holds last character from user input.
// (i.e '\n' or any other character besides numbers)
int flag; // Holds scanf return value
do{
flag = scanf("%d%c", &number, &buffer); // Gets input from user
// While scanf did not read 2 objects (i.e 1 int & 1 char)
// or the user inputed a number and then a character (eg. 12te)
// ask user to type a valid value
while (flag !=2 || buffer!='\n') {
clean_input();
printf("%s","You have typed non numeric characters.\n"
"Please type an integer\n?");
flag = scanf("%d%c", &number, &buffer);
}
if(number<0) {
printf("%s","You have typed a non positive integer\n"
"Please type a positive integer\n?");
} else { // If user typed a non negative value, exit do-while.
break;
}
}while(1);
}
void clean_input(void) {
while (getchar()!='\n');
return;
}
私の場合、数字を正にしたいだけです。番号を1〜23にするには、ifステートメントでnumber<0
をnumber<1 || number>23
に置き換えます。また、適切なメッセージを出力するには、printf
を変更する必要があります。