输入ASCII字符或float导致C语言scanf(%d)循环无限运行该如何修复
问题根因
这个无限循环的触发和char属于int子类的类型特性无关,完全是scanf的格式匹配规则导致的:
scanf("%d", &num)要求输入的内容必须是十进制整数格式的字符序列,当输入普通ASCII字符、带小数点的浮点数时,会触发格式匹配失败,此时会产生三个结果:- 错误输入的内容会残留在标准输入缓冲区中,不会被取走
scanf的返回值为0,代表本次成功赋值的变量数量为0- 目标变量
num的值不会被修改,会保留之前的有效数值
- 后续循环再次调用
scanf时,会重复读取缓冲区残留的错误内容,反复触发匹配失败,由此进入无限循环。 - 你提到的
char属于int的一种是C语言类型系统的存储特性,和scanf的格式校验逻辑没有关系:%d校验的是输入内容的格式,不是目标变量的类型兼容性,就算你用char类型变量接收%d的输入,输入非数字字符依然会触发匹配失败。
修复方法
需要增加scanf返回值校验,以及输入错误时的缓冲区清空逻辑,修改后代码如下:
#include <stdio.h> int main(void) { int num; int scan_ret; // 存储scanf的返回值 scan_ret = scanf("%d", &num); while (num < 40 || scan_ret != 1) { if (scan_ret != 1) { // 输入格式错误,清空缓冲区所有残留内容直到换行符 while (getchar() != '\n'); printf("输入不合法,请输入整数:\n"); } else { printf("Number is small\n"); } scan_ret = scanf("%d", &num); } return 0; }
修复逻辑说明
- 每次调用
scanf后都校验返回值,返回值为1才代表成功读取到了合法整数 - 输入格式错误时,通过
getchar循环读走缓冲区所有内容直到换行,清空残留的错误输入,避免下次读取重复失败 - 对合法但小于40的数值,保持原有提示逻辑,继续要求输入
内容的提问来源于stack exchange,提问作者arka
相关产品推荐
相关产品推荐

