C语言计算器代码使用scanf触发Clang-Tidy警告的原因是什么?
问题原因说明
1 Clang-Tidy警告触发原因
你看到的警告本质是Clang-Tidy针对scanf安全性的提示:scanf做格式转换时仅通过返回值告知成功匹配的参数个数,不会主动上报转换错误、范围溢出等问题,而多数开发者不会主动检查scanf的返回值,非法输入会直接导致逻辑异常。比如用户输入非数字字符给%f占位符时,scanf会匹配失败,对应的浮点变量会保留未初始化的垃圾值,后续计算完全错误,程序也不会给出任何提示。
如果要彻底消除该警告,可以改为先读取整行输入,再用strtof函数逐个转换数值,通过strtof的第二个参数可以明确检测转换是否成功、是否有非法字符。
2 代码存在的其他隐藏问题
- 格式串设计错误:
%f%c%f的写法会把运算符前后的空格、制表符、换行符当成运算符读取,导致匹配失败,需要改为%f %c %f,%c前的空格会自动跳过所有空白字符 - 二次输入残留问题:读取计算结果后的
scanf("%c", &playInput)会直接读取上一次输入残留的换行符,导致还没等用户输入y/n就直接跳过判断,同样需要在%c前加空格,改为scanf(" %c", &playInput) - 非法输入无处理:运算符匹配失败、输入格式错误、除零等异常场景没有任何处理逻辑,未初始化的
answer变量会直接输出垃圾值 - 头文件不规范:引入了不必要的
rpcndr.h头文件,boolean类型不是C标准原生类型,建议引入<stdbool.h>使用标准bool类型,兼容性更好
修复后的参考代码
#include <stdio.h> #include <stdbool.h> #include <ctype.h> int main() { bool playAgain = true; char playInput; float num1, num2, answer; char op; int matchCount; while (playAgain) { printf("Enter First Number, operator, second number: "); // 校验匹配成功的参数个数,同时跳过运算符前后的空白符 matchCount = scanf("%f %c %f", &num1, &op, &num2); if (matchCount != 3) { printf("Input format error, please try again\n"); // 清空输入缓冲区残留内容,避免死循环 while(getchar() != '\n'); continue; } bool validOp = true; switch (op) { case '*': answer = num1 * num2; break; case '/': if (num2 == 0) { printf("Error: division by zero\n"); validOp = false; break; } answer = num1 / num2; break; case '+': answer = num1 + num2; break; case '-': answer = num1 - num2; break; default: printf("Unsupported operator: %c\n", op); validOp = false; break; } if (validOp) { printf("Result: %f\n", answer); } printf("Do You Want To Try It Again(y/n)? "); // 跳过前面的空白符(包括残留的换行符) scanf(" %c", &playInput); // 清空输入缓冲区剩余内容 while(getchar() != '\n'); if (tolower(playInput) == 'n') { playAgain = false; } } return 0; }
内容的提问来源于stack exchange,提问作者Yesitha
相关产品推荐
相关产品推荐

