3

我正在查看 Beej 的IPC指南,一行代码引起了我的注意。

在特定页面中,while 循环speak.c有两个条件要检查while (gets(s), !feof(stdin))

所以我的问题是这怎么可能,正如我在大多数时候只测试一种情况时所看到的那样。

PS:我对这些不太陌生。将不胜感激任何帮助。谢谢!

4

4 回答 4

6

片段

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循环之前和循环体中的重复。

于 2012-05-02T15:02:07.320 回答
3

一些人已经指出了其中的一些问题。我当然同意使用gets(完全)是一个糟糕的想法。

我认为值得一提的另一个细节是:由于这feof(file)用作退出循环的条件,因此如果您在文件结束之前遇到错误,它可能/也会出现错误行为。发生错误时,将设置错误标志,但(通常)不会设置 EOF 标志 - 并且由于您无法再从文件中读取(由于错误),它也永远不会设置,所以这个将进入无限循环。

完成这项工作的正确方法是使用fgets,并检查其返回值:

while (fgets(s, length_of_s, stdin))
    process(s);

这将测试是否fgets 成功读取文件,因此它将退出文件结尾错误的循环。

另一个小细节:fgets读取字符串时,它通常会在行尾保留换行符(gets将其丢弃)。如果它存在,您可能需要添加更多代码才能将其剥离(并且如果换行符不存在,则可能处理比您分配的缓冲区更长的行)。

于 2012-05-02T15:23:41.673 回答
2

此测试使用逗号运算符,并已被用作获取下一行文本gets(s)并使用!feof(stdin).

于 2012-05-02T15:04:43.407 回答
2

此语法不计算两个表达式。它首先执行gets(s)然后评估!feof(stdin)可能被gets()函数调用修改的内容。

这不是一个很好的方法,因为它都使用gets(),这不是一个安全的功能,而且对于初学者来说很难阅读(因此你的问题)。

于 2012-05-02T15:05:17.433 回答