C编程 - 循环直到用户输入数字scanf

6

我希望能够帮助您进行程序的错误检查。我要求用户输入一个整数,并希望检查用户输入是否为整数,如果不是,请重复使用scanf。

我的代码:

int main(void){

  int number1, number2;
  int sum;

  //asks user for integers to add
  printf("Please enter the first integer to add.");
  scanf("%d",&number1);

  printf("Please enter the second integer to add.");
  scanf("%d",&number2);
  //adds integers
  sum = number1 + number2;

  //prints sum
  printf("Sum of %d and %d = %d \n",number1, number2, sum);

  //checks if sum is divisable by 3
  if(sum%3 == 0){
    printf("The sum of these two integers is a multiple of 3!\n");
  }else {
    printf("The sum of these two integers is not a multiple of 3...\n");
  }
  return 0;
}

4
了解forwhiledo-while循环。 - haccks
1
https://dev59.com/nWYq5IYBdhLWcg3w5ktm - NIlesh Sharma
此外,阅读有关 scanf(3) 的内容。它在成功时返回成功扫描的项目数! - Basile Starynkevitch
1
还要阅读关于 scanf 的内容,特别是它返回的内容。 - Some programmer dude
scanf() 函数的返回类型可以被检查。请详细参考相关文档。 - mahendiran.b
4个回答

9

scanf会根据您的格式返回成功读取的项目计数。您可以设置一个循环,只有当scanf("%d", &number2);返回1时才退出。然而,诀窍在于忽略scanf返回零时的无效数据,因此代码应该像这样:

while (scanf("%d",&number2) != 1) {
    // Tell the user that the entry was invalid
    printf("You did not enter a valid number\n");
    // Asterisk * tells scanf to read and ignore the value
    scanf("%*s");
}

如果你在代码中多次读取同一个数字,考虑编写一个函数来隐藏这个循环,并在main中调用该函数两次以避免重复。


1

这是你的问题的解决方案。我只是修改了一些你的代码。 阅读注释以获取任何解释。

#include<stdio.h>

#include<stdlib.h>      //included to use atoi()
#include<ctype.h>       //included to use isalpha()

#define LEN 3   //for two digit numbers

int main(void)
{

    char *num1=malloc(LEN);
    char *num2=malloc(LEN);
    int i,flag=0;

    int number1,number2;
    int sum;

    do
    {
        printf("Please enter the first integer to add = ");
        scanf("%s",num1);
        for (i=0; i<LEN; i++)   //check for every letter of num1
        {
            if (isalpha(num1[i]))   //isalpha(num1[i]) returns true if num1[i] is alphabet
            {                       //isalpha() is defined in ctype.h
                flag=1;             //set flag to 1 if num1[i] is a alphabet
            }
        }
        if(flag)
        {
            printf("Not a valid Integer\n");
            flag=0;
            continue;
        }
        else
        {
            break;
        }
    } while(1);

    do
    {
        printf("Please enter the second integer to add = ");
        scanf("%s",num2);
        for (i=0; i<LEN; i++)
        {
            if (isalpha(num2[i]))
            {
                flag=1;
            }
        }
        if(flag)
        {
            printf("Not a valid Integer\n");
            flag=0;
            continue;
        }
        else
        {
            break;
        }
    } while(1);

    //strings to integers
    number1= atoi(num1);    //atoi() is defined in stdlib.h
    number2= atoi(num2);

    //adds integers
    sum = number1 + number2;

    //prints sum
    printf("Sum of %d and %d = %d \n",number1, number2, sum);

    //checks if sum is divisable by 3
    if(sum%3 == 0)
    {
        printf("The sum of these two integers is a multiple of 3!\n");
    }
    else
    {
        printf("The sum of these two integers is not a multiple of 3...\n");
    }
    return 0;
}

我设计这个程序只针对两位数,但是对于超过两位数的情况在我的电脑上也能正常运行。请告诉我在你的电脑上是否也是这样。
如果你知道为什么会这样,请留言告诉我。
你也可以使用strtol()代替atoi()。我没有使用它是因为数值较小。 atoi()strtol()之间的区别: atoi()
优点: 简单易用。
优点: 转换成int整型。
优点: 在C标准库中。
优点: 运行速度快。
缺点: 没有错误处理。
缺点: 不能处理十六进制和八进制数。 strtol()
优点: 简单易用。
优点: 在C标准库中。
优点: 错误处理好。
优点: 运行速度快。
缺点: 转换成long型而不是int型,大小可能会有所不同。

0

我想说的是,您需要进行一些自定义验证来检查scanf是否读取了整数。我使用fgets而不是scanf

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

int validate ( char *a )
{
  unsigned x;
  for ( x = 0; x < strlen ( a ); x++ )
    if ( !isdigit ( a[x] ) ) return 1;
  return 0;
}

int main ( void )
{
  int i;
  char buffer[BUFSIZ];
  printf ( "Enter a number: " );
  if ( fgets ( buffer, sizeof buffer, stdin ) != NULL ) {
    buffer[strlen ( buffer ) - 1] = '\0';
    if ( validate ( buffer ) == 0 ) {
      i = atoi ( buffer );
      printf ( "%d\n", i );
    }
    else
      printf ( "Error: Input validation\n" );
  }
  else
    printf ( "Error reading input\n" );
  return 0;
}

isdigit的参数必须转换为*unsigned char*。 - Antti Haapala -- Слава Україні

0

解决这个问题的一种简洁方法是:

  1. 使用 fgets()stdin 中读取。

  2. 使用 strtol() 将值转换并存储为 int。然后检查 char **endptr 是否成功转换 [表示整数]。

  3. 执行剩余任务。


使用 fgets() 是一个好的方法,但是没有必要使用 isdigit() 进行“验证”;只需尝试使用 strtol() 并检查其“结束指针”,以查看它是否消耗了任何输入。 - unwind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接