C语言使用CS50库时如何实现1-3范围操作选项的输入校验
圆计算器输入校验问题
问题背景
开发基于CS50库的圆计算器程序,逻辑为依次获取用户选择的运算类型(周长/面积/体积)、半径参数,要求当用户输入的运算选项不是1-3范围内的有效值时,输出错误提示please enter a number from 1 to 3。
当前代码存在缺陷:无法覆盖非数字输入的场景。
最初误判问题原因是运算选项的变量声明为浮点型,实际测试后确认:
- 代码使用
get_int获取运算选项,该函数遇到非整数输入时会自动重新提示用户输入,不会返回无效值 - 仅当用户输入1、2、3之外的整数时,才会触发else分支的错误提示
- 输入字母、特殊符号等非数字内容时,无法触发自定义的错误提示
现有问题代码
#include <stdio.h> #include <cs50.h> void get_circum(float radius); void get_area(float radius); void get_volume(float radius); int main (void){ printf("welcome in circle calculator,please select operation! \n"); int operation = get_int("1-circumference \n2-area \n3-volume \n"); if(operation==1 || operation==2 || operation==3){ float radius = get_float("radius: \n"); if(operation==1){get_circum(radius);} else if(operation==2){get_area(radius);} else if(operation==3){get_volume(radius);} } else if(operation !=1 && operation !=2 && operation !=3){ printf("please enter a number from 1 to 3"); } }
问题根因
CS50库的get_int自带内置校验逻辑:检测到非整数输入时会自动丢弃无效输入、重新弹出提示要求用户重输,整个过程在函数内部完成,不会把非整数的无效值返回给调用方,因此代码里写的范围判断分支永远捕获不到非数字类的无效输入。
修复方法
放弃直接调用get_int获取选项,改用get_string读取用户的原始输入字符串,自行完成整数转换、合法性校验,即可覆盖所有无效输入场景,输出自定义错误提示。
修复后的完整代码示例:
#include <stdio.h> #include <cs50.h> #include <ctype.h> #include <stdlib.h> #include <string.h> void get_circum(float radius); void get_area(float radius); void get_volume(float radius); int main (void){ printf("welcome in circle calculator,please select operation! \n"); int operation; bool valid_input = false; // 循环校验直到拿到合法输入 while(!valid_input) { char *op_str = get_string("1-circumference \n2-area \n3-volume \n"); // 先校验输入是否为纯单个数字字符 if(strlen(op_str) == 1 && isdigit(op_str[0])) { operation = atoi(op_str); if(operation >=1 && operation <=3) { valid_input = true; } } // 所有无效场景统一输出提示 if(!valid_input) { printf("please enter a number from 1 to 3\n"); } } float radius = get_float("radius: \n"); if(operation==1){get_circum(radius);} else if(operation==2){get_area(radius);} else if(operation==3){get_volume(radius);} return 0; }
注意:编译时需要链接CS50库,上述代码新增了
ctype.h、string.h、stdlib.h头文件用于字符串处理和类型转换。
内容的提问来源于stack exchange,提问作者A7mad 3arafa
相关产品推荐
相关产品推荐

