我正在查看 Beej 的IPC指南,一行代码引起了我的注意。
在特定页面中,while 循环speak.c
有两个条件要检查while (gets(s), !feof(stdin))
。
所以我的问题是这怎么可能,正如我在大多数时候只测试一种情况时所看到的那样。
PS:我对这些不太陌生。将不胜感激任何帮助。谢谢!
片段
while (gets(s), !feof(stdin))
使用逗号运算符,首先执行gets(s)
,然后测试!feof(stdin)
,这是条件的结果。
顺便说一句,不要使用 gets,这是非常不安全的。警惕使用它的资源,它们可能不是学习语言的好资源。
编码
while(gets(s), !feof(stdin)) {
/* loop body */
}
相当于
gets(s);
while(!feof(stdin)) {
/* loop body */
gets(s);
}
更简洁,因为它避免了gets
循环之前和循环体中的重复。
一些人已经指出了其中的一些问题。我当然同意使用gets
(完全)是一个糟糕的想法。
我认为值得一提的另一个细节是:由于这feof(file)
用作退出循环的条件,因此如果您在文件结束之前遇到错误,它可能/也会出现错误行为。发生错误时,将设置错误标志,但(通常)不会设置 EOF 标志 - 并且由于您无法再从文件中读取(由于错误),它也永远不会设置,所以这个将进入无限循环。
完成这项工作的正确方法是使用fgets
,并检查其返回值:
while (fgets(s, length_of_s, stdin))
process(s);
这将测试是否fgets
成功读取文件,因此它将退出文件结尾或错误的循环。
另一个小细节:fgets
读取字符串时,它通常会在行尾保留换行符(gets
将其丢弃)。如果它存在,您可能需要添加更多代码才能将其剥离(并且如果换行符不存在,则可能处理比您分配的缓冲区更长的行)。
此测试使用逗号运算符,并已被用作获取下一行文本gets(s)
并使用!feof(stdin)
.
此语法不计算两个表达式。它首先执行gets(s)
然后评估!feof(stdin)
可能被gets()
函数调用修改的内容。
这不是一个很好的方法,因为它都使用gets()
,这不是一个安全的功能,而且对于初学者来说很难阅读(因此你的问题)。