14

下面是一些 C 代码,试图阻止用户输入小于 0 或大于 23 的字符或整数。

#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;  
}

我做到了一半,一个小的俯卧撑将不胜感激。

4

5 回答 5

37

使用scanf("%d",&rows)代替scanf("%s",input)

这允许您直接从标准输入获取整数值,而无需转换为 int。

如果用户输入一个包含非数字字符的字符串,那么您必须在下一个之前清理您的标准输入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。Nothing capted

示例 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')

在example1中:这个条件是TRUE因为scanf return0(!=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 中: is(scanf("%d%c", &rows, &c)!=2 || c!='\n')所以TRUE应该&&检查之后的条件,所以clean_stdin()将执行并且整个条件是TRUE

在示例 2 中: The(scanf("%d%c", &rows, &c)!=2 || c!='\n')isFALSEso that the condition after the&&will not check (因为它的结果是整个条件将是FALSE) 所以clean_stdin()不会执行并且整个条件是FALSE

在示例 3 中: is(scanf("%d%c", &rows, &c)!=2 || c!='\n')所以TRUE应该&&检查之后的条件,所以clean_stdin()将执行并且整个条件是TRUE

所以你可以说clean_stdin()只有当用户输入一个包含非数字字符的字符串时才会执行。

并且仅当用户输入 an而没有其他内容时,此条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())才会返回FALSEinteger

如果条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())FALSE并且integer介于和之间123while循环将中断,否则while循环将继续

于 2012-12-31T08:51:46.923 回答
3
#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;
}

%[^0-9]inscanf()吞噬了所有不在 and 之间0的东西9。基本上它会清除非数字的输入流并将其放入str. 好吧,非数字序列的长度限制为 100。以下%d仅选择输入流中的整数并将其放入num.

于 2013-07-22T10:54:27.627 回答
1

您可以创建一个读取 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;
}
于 2012-12-31T10:13:42.323 回答
1
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用作输入。

于 2016-04-18T21:14:15.957 回答
0

您将需要strtol在您要求用户重试的循环内部重复调用。事实上,如果你让循环 ado { ... } while(...);而不是 while,你不会得到相同类型的重复事情两次的行为。

您还应该格式化您的代码,以便可以看到代码在循环内的位置而不是循环内的位置。

于 2012-12-31T08:55:11.787 回答