我们可以在没有&& / ||的情况下同时循环测试两个参数

时间:2012-05-02 15:00:05

标签: c ipc

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

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

所以我的问题是,在我看到大部分时间只测试一种情况时,这是怎么可能的。

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

5 个答案:

答案 0 :(得分:6)

摘录

while (gets(s), !feof(stdin))

使用逗号运算符,首先执行gets(s),然后测试!feof(stdin),这是条件的结果。

顺便说一句不要使用获取,这是非常不安全的。警惕使用它的消息来源,它们可能不是学习该语言的好资源。

代码

while(gets(s), !feof(stdin)) {
    /* loop body */
}

相当于

gets(s);
while(!feof(stdin)) {
    /* loop body */
    gets(s);
}

更简洁,因为它避免了在循环之前和循环体中重复gets

答案 1 :(得分:3)

有几个人已经指出了一些问题。我当然同意使用gets(根本没有)是一个糟糕的想法。

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

正确的工作方式是使用fgets,并检查其返回值:

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

在从文件读取时测试fgets 成功,因此它将退出文件的任一端或错误的循环。

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

答案 2 :(得分:2)

此测试使用的是comma operator,并且已被用作使用gets(s)获取下一行文本并使用!feof(stdin)测试文件结尾的方法。

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

我同意@DanielFischer和@trojanfoe,逗号运营商。

另外需要注意的一点是,您通常不想使用它,尤其是在上述问题的上下文中。作为一名专业编码员,它会使您的代码更易于阅读,并且对其他开发人员来说更加混乱,因此有一次攻击。

另外,如果您使用静态代码分析工具(如LINT(http://en.wikipedia.org/wiki/PC-Lint)),它会向您发出大量警告,因此还有另一个问题如果你想要专业的质量代码。

最后,正如@DanielFischer所说,gets()根本不安全,并且负责许多漏洞和溢出错误。请改用fgets()函数,因为它允许您设置要读取的字符数的上限。

http://www.cplusplus.com/reference/clibrary/cstdio/fgets/

你不会后悔习惯总是使用fgets()代替获取,特别是如果这是生产代码。

您也可以考虑查看安全字符串函数。

http://linux.die.net/man/3/snprintf

它们不是标准ANSI / C99 C的一部分,但如果您只是为某个平台开发,它们会阻止您崩溃程序或打开安全漏洞。

祝你好运!