编写一个需要整数输入并返回其他数据类型错误的程序

Writing a Program that expects an integer input and returns an error for other data types

提问人:Chlaus 提问时间:11/3/2023 更新时间:11/3/2023 访问量:115

问:

我正在尝试编写一个代码,该代码返回获取整数数据类型以外的输入的错误。

void error() {
    printf("Invalid Input. Please Try Again.");
    exit(0); //terminate program after invalid input
}

int main() {
    
    int myHW, myQ, myME, myFE, myGrade; //score variables
    
    printf("Grade Calculation Program\n***************************\n\n"); //header

    printf("Please enter your scores.\n");
    
    printf("Homework Score (out of 20): "); //homework score
    ( scanf("%d", &myHW) == 1) ? : error(); 
    (myHW>=0 && myHW<=20) ? : error(); 
    
    
    printf("Quiz Score (out of 30): "); //quiz score
    ( scanf("%d", &myQ) == 1) ? : error();
    (myQ>=0 && myQ<=30) ? : error(); 
    
    printf("Midterm Exam Score (out of 20): "); //midterm exam score
    ( scanf("%d", &myME) == 1) ? : error();
    (myME>=0 && myME<=20) ? : error(); 
    
    printf("Final Exam Score (out of 30): "); //final exam score
    ( scanf("%d", &myFE) == 1) ? : error();
    (myFE>=0 && myFE<=30) ? : error(); 

我试过使用

( scanf("%d", &myHW) == 1) ? : error();

但是,只有当用户输入的第一个字符是字符/字母开头时(a、f25、bd236.5 是我尝试过的一些输入),或者如果字符/小数之前的整数已经越界(例如 25a、28bd、29.5),程序才会返回错误。如果我尝试一个浮点/双精度数据类型的输入或仍在参数范围内的整数组合,后跟一个字符(例如 12.5、5.3、5A),程序会先跳到下一行,然后再传递错误。

请输入您的分数。 家庭作业分数(满分 20 分):5a 测验分数(满分 30 分):输入无效。请再试一次。

这是上述错误的一个实例。

我知道这与我在条件中使用 scanf 的返回值有关。据我所知,只要输入以数字开头,scanf 就会返回 1。我对编程相当陌生,我只是想尝试解决我们的教授给出的一些问题,但我似乎无法为这个问题想出解决方案

c 扫描

评论

3赞 pmg 11/3/2023
用于用户输入。fgets()
0赞 Jeff Holt 11/3/2023
在 %d 之后添加一个 %s,以便捕获数字后面的内容。如果 scanf 返回 0 或 2,则表示您发现错误。
4赞 Ted Lyngmo 11/3/2023
请注意,这不是标准的 C:,而且读起来也很糟糕。来得及。(scanf("%d", &myHW) == 1) ?: error();if(scanf("%d", &myHW) != 1) error();
5赞 Harith 11/3/2023
之后,用于转换。请参见:stackoverflow.com/a/14176593/20017547fgets()strtol()
1赞 chux - Reinstate Monica 11/3/2023
@Chlaus令人困惑。出错时,您打算再次尝试输入还是退出?该选择首先会影响如何读取整数。printf("Invalid Input. Please Try Again."); exit(0);

答:

0赞 NoDakker 11/3/2023 #1

在尝试您的代码时,我看到了一些可以增强用户体验的领域,可以使用标准字符和数字功能,以及一些可以整合的冗余。因此,下面是代码的重构版本,应使用户体验更加流畅。

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

void error()
{
    printf("Invalid Input. Please Try Again.\n");
    return;
}

int allDigits(char *word)
{
    for (int i = 0; i < strlen(word); i++)
    {
        if ((word[i] == '\0') || (word[i] == 10))   /* Reached the terminator or newline character  */
            return 1;
        if (isdigit(word[i]) == 0)                  /* Standard ctype.h function                    */
            return 0;
    }
    return 1;
}

int getInput(char *input_type, int max)
{
    char inp[10];
    int result;
    while (1)
    {
        printf("%s", input_type);
        if (fgets(inp, 4, stdin) == NULL)
        {
            error();
            continue;
        }
        if (allDigits(inp) == 0)
        {
            error();
            continue;
        }
        result = atoi(inp);
        if (result < 0 || result > max)
        {
            error();
            continue;
        }
        break;
    }
    return result;
}

int main()
{
    int myHW, myQ, myME, myFE, myGrade;         //score variables

    printf("Grade Calculation Program\n***************************\n\n"); //header

    printf("Please enter your scores.\n");

    myHW = getInput("Homework Score (out of 20)....: ", 20);    /* Homework score       */
    myQ  = getInput("Quiz Score (out of 30)........: ", 30);    /* Quiz score           */
    myME = getInput("Midterm Exam Score (out of 20): ", 20);    /* Midterm exam         */
    myFE = getInput("Final Exam Score (out of 30)..: ", 30);    /* Final exam           */

    myGrade = myHW + myQ + myME + myFE;

    printf("Recap:\nHomework....: %d\nQuiz........: %d\nMidterm Exam: %d\nFinal Exam..: %d\n- - - - - - - - -\nTotal Score.: %d\n", myHW, myQ, myME, myFE, myGrade);

    return 0;
}

在此重构的代码中要指出的一些关键位。

  • 添加了“string.h”和“ctype.h”包含文件,以允许使用标准字符和数字检查以及字符串数据到整数数据的标准转换。
  • 在好评中指出,告诉用户发生了某种类型的输入错误,然后退出程序似乎使用户体验有点模糊,因此退出更改为返回以允许用户重试输入。
  • 在好评中还指出,“fgets()”函数可能是用户输入的更好选择,这在重构的代码中发生了变化。
  • 注意到大量冗余函数调用和输入验证导致将冗余代码从主函数中提取出来,并将其包装在一个通用函数中,该函数可以重用于每个类别的输入(例如家庭作业、测验、期中考试和期末考试),从而减小程序的大小。
  • 通过有根据的猜测,完成代码以计算总分并打印学生的统计数据。

通过这些重构,以下是学生的示例输出。

craig@Vera:~/C_Programs/Console/Scores/bin/Release$ ./Scores 
Grade Calculation Program
***************************

Please enter your scores.
Homework Score (out of 20)....: 17
Quiz Score (out of 30)........: 25
Midterm Exam Score (out of 20): 13
Final Exam Score (out of 30)..: 28
Recap:
Homework....: 17
Quiz........: 25
Midterm Exam: 13
Final Exam..: 28
- - - - - - - - -
Total Score.: 83

查看此重构的代码,并将其用作思考的食粮。并且始终注意在重复类似或相同的功能时可以重构代码的位置。它通常是一个信号,表明重复的步骤可以封装在一个函数中,然后可以使用不同的输入参数多次调用该函数。与往常一样,请始终参考有关在语言中使用标准函数的可用编码教程,以避免不必要地重新创建现有功能。

评论

0赞 Armali 11/3/2023
我认为将空输入行作为零的行为不会使用户体验流畅,尤其是在输入了 3 位数字之后。
0赞 Chlaus 11/12/2023
感谢您的重构代码以及建议!这里使用的大多数语法还没有在我们的讲座中涵盖,但我花时间研究每个函数,并尽我所能遵循算法的流程。我现在的教授接受了我的初始代码,因为我们仍在讨论 If...还。。。语句。虽然这不是问题所必需的,但我想提供某种错误处理算法。我还没有太多的编程知识,所以我以前的输出是我能想到的最好的。