read from stdin, and write to stdout, why my read() function always return 1?

huangapple go评论66阅读模式
英文:

read from stdin, and write to stdout, why my read() function alwasy return 1?

问题

我有一个简单的代码来测试read()write()系统调用,如下所示:

```c
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>

int main()
{
    #define BUFFSIZE 4096
    int n;
    char buf[BUFFSIZE];

    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0) {

        if (write(STDOUT_FILENO, buf, n) != n) {
            printf("write err.\n");
        }
    }
    if (n < 0) {
        printf("read error.\n");
    }
    return 0;
}

我像这样运行它:

$ ./a.out 
hello
h




我使用gdb并发现read()始终返回1。


<details>
<summary>英文:</summary>

I have a simple code to test read() and write() system call, as below

```c
#include&lt;stdlib.h&gt;
#include&lt;unistd.h&gt;
#include&lt;stdio.h&gt;

int main()
{
    #define BUFFSIZE 4096
    int n;
    char buf[BUFFSIZE];

    while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) {

        if (write(STDOUT_FILENO, buf, n) != n) {
            printf(&quot;write err.\n&quot;);
        }
    }
    if (n &lt; 0) {
        printf(&quot;read error.\n&quot;);
    }
    return 0;
}

and I run it like this:

$ ./a.out 
hello
h




I use gdb and find read() always returns 1.

答案1

得分: 3

The statement:

while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) 

is parsed as:

while ( n = (read (STDIN_FILENO, buf, BUFSIZE) &gt; 0))

The comparison operator &gt; has higher precedence than the assignment operator =. Comparison and logical operators return the value false or true, which in this statement gets stored in the variable n. You need parentheses around the assignment to n in order to secure the order of operations like so:

while ( (n = read (STDIN_FILENO, buf, BUFSIZE)) &gt; 0)

Alternatively, the loop can be rewritten in this manner:

for (;;) {
    n = read (STDIN_FILENO, buf, BUFSIZE);
    if (n &lt;= 0) {
        break;
    }

    if (write (STDOUT_FILENO, buf, n) != n) {
        fputs ("write error.\n", stderr);
    }
}

Note that read() returns a ssize_t, not an int.

英文:

The statement:

while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) 

is parsed as:

while ( n = (read (STDIN_FILENO, buf, BUFSIZE) &gt; 0))

The comparison operator &gt; has higher precedence than the assignment operator =. Comparison and logical operators return the value false or true, which in this statement gets stored in the variable n. You need parentheses around the assignment to n in order to secure order of operations like so:

while ( (n = read (STDIN_FILENO, buf, BUFSIZE)) &gt; 0)

Alternatively, the loop can be rewritten in this manner:

for (;;) {
    n = read (STDIN_FILENO, buf, BUFSIZE);
    if (n &lt;= 0) {
        break;
    }

    if (write (STDOUT_FILENO, buf, n) != n) {
        fputs (&quot;write error.\n&quot;, stderr);
    }
}

Note that read() returns a ssize_t, not an int.

答案2

得分: 2

你必须在while条件中加上括号,否则 nread(STDIN_FILENO, buf, BUFFSIZE)) &gt; 0 的结果。

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    #define BUFFSIZE 4096
    int n;
    char buf[BUFFSIZE];

    while ((n=read(STDIN_FILENO, buf, BUFFSIZE)) > 0) {

        if (write(STDOUT_FILENO, buf, n) != n) {
            printf("write err.\n");
        }
    }
    if (n < 0) {
        printf("read error.\n");
    }
    return 0;
}
英文:

You must put parentheses in the while condition, otherwise n is the result of read(STDIN_FILENO, buf, BUFFSIZE)) &gt; 0.

#include&lt;stdlib.h&gt;
#include&lt;unistd.h&gt;
#include&lt;stdio.h&gt;

int main()
{
    #define BUFFSIZE 4096
    int n;
    char buf[BUFFSIZE];

    while ((n=read(STDIN_FILENO, buf, BUFFSIZE)) &gt; 0) {

        if (write(STDOUT_FILENO, buf, n) != n) {
            printf(&quot;write err.\n&quot;);
        }
    }
    if (n &lt; 0) {
        printf(&quot;read error.\n&quot;);
    }
    return 0;
}

答案3

得分: 0

高级问题

节省时间。启用所有警告。比在SO上发帖更有效。

while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) {

警告:建议在用作真值的赋值周围加上括号[-Wparentheses]

以及其他。

英文:

Higher level problem

Save time. Enable all warnings. More efficient than posting on SO.

while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) {

warning: suggest parentheses around assignment used as truth value [-Wparentheses]

and others.

huangapple
  • 本文由 发表于 2023年5月22日 17:37:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76304818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定