You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 22:15:01