如何避免短整型变量因输入溢出引发的转换错误问题?
问题描述
我需要实现仅当用户输入6时执行特定代码,但当前代码存在安全问题:使用short int x存储输入,通过scanf("%d", &x)读取值时,若输入65442(超过系统SHRT_MAX值32767),该值会被转换为6,意外触发目标代码。我不想改用int或long int存储x,请问该如何解决?
当前代码:
#include<stdio.h> int main(void) { short int x; printf("Val :"); scanf("%d", &x); if (x == 6) { //some code } return 0; }
解决方案
方法1:先读取到int变量,验证范围与值
核心思路是先将输入读取到足够大的int变量中,在赋值给short前完成两项检查:输入值是否恰好为6,且该值在short的有效范围内(避免赋值时的溢出问题)。
#include <stdio.h> #include <limits.h> int main(void) { int input_val; short int x; printf("Val :"); // 检查输入是否成功读取为整数 if (scanf("%d", &input_val) != 1) { fprintf(stderr, "输入无效,请输入整数\n"); return 1; } // 仅当输入值恰好为6,且在short的合法范围内时,才执行目标代码 if (input_val == 6 && input_val >= SHRT_MIN && input_val <= SHRT_MAX) { x = (short)input_val; // 此时赋值无溢出风险 // 执行你的特定代码 printf("触发特定代码\n"); } else { printf("输入不符合要求\n"); } return 0; }
方法2:读取字符串并严格匹配
如果需要更严格的输入校验(比如拒绝06这类非精确输入),可以直接读取输入字符串,判断是否与"6"完全一致,彻底规避数值转换的溢出问题:
#include <stdio.h> #include <string.h> int main(void) { char input_buf[64]; printf("Val :"); // 读取整行输入 if (fgets(input_buf, sizeof(input_buf), stdin) == NULL) { fprintf(stderr, "输入失败\n"); return 1; } // 去除换行符(如果存在) input_buf[strcspn(input_buf, "\n")] = '\0'; // 严格匹配输入字符串是否为"6" if (strcmp(input_buf, "6") == 0) { short int x = 6; // 执行你的特定代码 printf("触发特定代码\n"); } else { printf("输入不符合要求\n"); } return 0; }
问题根源
原代码中scanf("%d", &x)会将输入解析为int类型,再赋值给short int变量。当输入值超过SHRT_MAX时,会触发有符号整数溢出,这属于C标准中的未定义行为。在多数系统中,溢出的值会被截断为short的低16位,导致意外得到6,从而错误触发目标逻辑。
内容的提问来源于stack exchange,提问作者Mildred Gallagher
相关产品推荐
相关产品推荐

