如何确保使用%ld格式时fscanf()返回溢出错误?
关于fscanf整数溢出的问题解答
首先明确几个核心点:
- 按C标准及常见实现(比如glibc),fscanf处理整数溢出时不会返回EOF。它会把目标变量设为对应类型的极值(比如long型就是LONG_MIN或LONG_MAX),然后返回成功匹配的项数(通常是1),部分实现会将errno设为ERANGE,但这并非标准强制要求。
- strtol的溢出逻辑确实是返回极值并设置errno为ERANGE,但fscanf内部即便复用了类似逻辑,也不会把这类错误转化为EOF返回——EOF仅在输入到达末尾、发生IO错误时才会触发。
你问的用%10ld能不能确保溢出时返回EOF?答案是不能:
%10ld只是限制最多读取10个字符来解析long型整数,没法彻底避免溢出。比如32位long的最大值是2147483647(10位),若输入是9999999999(10位),明显超出long范围,fscanf仍会把变量设为LONG_MAX,返回1,不会返回EOF。- 哪怕限制了字符数,只要输入的数字值超出long的取值范围,溢出就会发生,fscanf的返回值不会变成EOF。
如果想要100%检测到溢出并终止读取,更可靠的做法是:
- 用
fgets()读取一行或固定长度的字符串到缓冲区; - 用
strtol()转换该字符串,同时检查:- 转换后的errno是否为ERANGE(判断溢出/下溢);
- 检查转换后的剩余字符是否为空白或结束符(确保输入是合法整数,无多余非数字字符);
- 一旦检测到溢出,直接终止处理即可。
内容的提问来源于stack exchange,提问作者sneaker
相关产品推荐
相关产品推荐

