【发布时间】:2015-08-13 06:50:33
【问题描述】:
一个典型的成语是:
if (scanf("%d%d%d", &a, &b &c) != 3)
handle_the_failure();
这个3,字段数,是多余的。如果我将模式和参数更改为scanf(..),但忘记更改3,那就是另一个编译-测试-调试循环,浪费时间。
是否有一个成语可以检查scanf(..) 的(绝对)成功,而无需在代码中写入字段数?也许是这样的:
scanf("%d%d%d", &a, &b &c);
if (lastScanfFailedInAnyWay())
handle_the_failure();
documentation(参见“返回值”部分)讨论了四种不同的条件:
文件结束
读取错误
匹配失败
解释宽字符时出现编码错误
前两个由feof(..) 和ferror(..) 处理(我假设feof(..) 暗示ferror(..)),最后一个- 通过将errno 设置为EILSEQ。但我对包罗万象(即包括确定是否发生匹配失败)感兴趣。
附:看看上面简洁的断章取义的例子,这似乎要求太多,但考虑一下实际实践,你可以快速做出许多改变,并且要记住数百个这样的小事情,每次你改变一件事,你必须在别处改变另一件事。然后很明显,养成消除各种依赖的习惯是有回报的。
【问题讨论】:
-
不要假设
feof可以返回“true”而ferror返回“false”,反之亦然。并且不要检查errno,除非最后一个函数调用实际上失败并且被指定为实际设置errno(scanfand family 不是)。如果将errno设置为失败的函数没有失败,则errno的值未指定。 -
否;除了检查返回的数字是否是预期的数字之外,没有可靠的方法来确定
scanf()家庭例程是否有效。当你做出改变时,你必须思考。即使您进行了数百次更改,您也必须考虑每一项,并确保您做出了正确的更改。欢迎来到编程的世界——对细节的偏执关注是你获得高薪的原因。顺便说一句,如果您使用 GCC 并设置了足够多的警告选项,系统会告诉您是否与格式字符串和其他参数不匹配,但它不会告诉您进行了错误的比较。 -
@JonathanLeffler 我正在等待欢迎你进入编程世界的那一天,在那里你会因为好的想法而获得报酬。