我试图编写一个代码,该代码在获取除整数数据类型之外的输入时返回错误。
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。我对编程相当陌生,我只是想尝试解决我们教授给出的一些问题,但我似乎无法为此找到解决方案
在尝试您的代码时,我看到一些可以增强用户体验的领域,可以使用标准字符和数字功能,以及一些可以合并的冗余。因此,以下是代码的重构版本,它应该使用户体验更加流畅。
#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;
}
在此重构代码中需要指出的一些关键位。
通过这些重构,以下是学生的示例输出。
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
回顾这段重构的代码并将其作为思考的基础。当重复类似或相同的功能时,始终留意可以重构代码的地方。这通常是一个信号,表明重复的步骤可以封装在一个函数中,然后可以使用不同的输入参数多次调用该函数。一如既往,请始终参考有关在语言中使用标准函数的可用编码教程,以避免不必要地重新创建现有功能。