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

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

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

问题

  1. 我有一个简单的代码来测试read()write()系统调用,如下所示:
  2. ```c
  3. #include<stdlib.h>
  4. #include<unistd.h>
  5. #include<stdio.h>
  6. int main()
  7. {
  8. #define BUFFSIZE 4096
  9. int n;
  10. char buf[BUFFSIZE];
  11. while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0) {
  12. if (write(STDOUT_FILENO, buf, n) != n) {
  13. printf("write err.\n");
  14. }
  15. }
  16. if (n < 0) {
  17. printf("read error.\n");
  18. }
  19. return 0;
  20. }

我像这样运行它:

  1. $ ./a.out
  2. hello
  3. h

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

  1. <details>
  2. <summary>英文:</summary>
  3. I have a simple code to test read() and write() system call, as below
  4. ```c
  5. #include&lt;stdlib.h&gt;
  6. #include&lt;unistd.h&gt;
  7. #include&lt;stdio.h&gt;
  8. int main()
  9. {
  10. #define BUFFSIZE 4096
  11. int n;
  12. char buf[BUFFSIZE];
  13. while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) {
  14. if (write(STDOUT_FILENO, buf, n) != n) {
  15. printf(&quot;write err.\n&quot;);
  16. }
  17. }
  18. if (n &lt; 0) {
  19. printf(&quot;read error.\n&quot;);
  20. }
  21. return 0;
  22. }

and I run it like this:

  1. $ ./a.out
  2. hello
  3. h

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

答案1

得分: 3

The statement:

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

is parsed as:

  1. 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:

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

Alternatively, the loop can be rewritten in this manner:

  1. for (;;) {
  2. n = read (STDIN_FILENO, buf, BUFSIZE);
  3. if (n &lt;= 0) {
  4. break;
  5. }
  6. if (write (STDOUT_FILENO, buf, n) != n) {
  7. fputs ("write error.\n", stderr);
  8. }
  9. }

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

英文:

The statement:

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

is parsed as:

  1. 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:

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

Alternatively, the loop can be rewritten in this manner:

  1. for (;;) {
  2. n = read (STDIN_FILENO, buf, BUFSIZE);
  3. if (n &lt;= 0) {
  4. break;
  5. }
  6. if (write (STDOUT_FILENO, buf, n) != n) {
  7. fputs (&quot;write error.\n&quot;, stderr);
  8. }
  9. }

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

答案2

得分: 2

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

  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. int main()
  5. {
  6. #define BUFFSIZE 4096
  7. int n;
  8. char buf[BUFFSIZE];
  9. while ((n=read(STDIN_FILENO, buf, BUFFSIZE)) > 0) {
  10. if (write(STDOUT_FILENO, buf, n) != n) {
  11. printf("write err.\n");
  12. }
  13. }
  14. if (n < 0) {
  15. printf("read error.\n");
  16. }
  17. return 0;
  18. }
英文:

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

  1. #include&lt;stdlib.h&gt;
  2. #include&lt;unistd.h&gt;
  3. #include&lt;stdio.h&gt;
  4. int main()
  5. {
  6. #define BUFFSIZE 4096
  7. int n;
  8. char buf[BUFFSIZE];
  9. while ((n=read(STDIN_FILENO, buf, BUFFSIZE)) &gt; 0) {
  10. if (write(STDOUT_FILENO, buf, n) != n) {
  11. printf(&quot;write err.\n&quot;);
  12. }
  13. }
  14. if (n &lt; 0) {
  15. printf(&quot;read error.\n&quot;);
  16. }
  17. return 0;
  18. }

答案3

得分: 0

高级问题

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

  1. while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) {
  2. 警告:建议在用作真值的赋值周围加上括号[-Wparentheses]

以及其他。

英文:

Higher level problem

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

  1. while (n=read(STDIN_FILENO, buf, BUFFSIZE) &gt; 0) {
  2. 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:

确定