【问题标题】:Is it necessary to use a while loop when using the read and write system calls?使用读写系统调用时是否需要使用while循环?
【发布时间】:2020-05-04 09:21:40
【问题描述】:

我正在练习读写系统调用,下面的代码在使用 while 循环和没有它们的情况下都可以正常工作。你能告诉我这里的while循环有什么用吗,是否有必要在使用读写系统调用时添加它。我是初学者。谢谢。

#include <unistd.h>
#define BUF_SIZE 256
int main(int argc, char *argv[])
{
    char buf[BUF_SIZE];    
    ssize_t rlen;
    int i; 
    char from;
    char to;
    from = 'e';
    to = 'a';

    while (1) {
        rlen = read(0, buf, sizeof(buf));
        if (rlen == 0)
               return 0;

        for (i = 0; i < rlen; i++) {
               if (buf[i] == from)
                      buf[i] = to;
        }
    write(1, buf, rlen);
   }
return 0;
}


【问题讨论】:

  • 如果您要阅读的消息超过256 个字符怎么办?如果要读取的消息超过SSIZE_MAX,则必须多次重复操作。
  • 使用while 循环,您可以在有可用数据时继续阅读。没有它,您只能阅读一次。哪一种更合适取决于预期的外部行为是什么。
  • 如果出现错误会无限循环,最好查看&lt;= 0
  • @Ôrel 是的,谢谢。
  • @kiranBiradar 是的,现在我明白了,谢谢。

标签: c linux operating-system


【解决方案1】:

您通常需要将while 循环(或一般的某种循环)与readwrite 一起使用,因为您应该从手册页(man 2 read)中知道:

RETURN VALUE

On success, the number of bytes read is returned (zero indicates end
of file), and the file position is advanced by this number.  It is
not an error if this number is smaller than the number of bytes
requested; this may happen for example because fewer bytes are
actually available right now (maybe because we were close to end-of-
file, or because we are reading from a pipe, or from a terminal), or
because read() was interrupted by a signal.  See also NOTES.

因此,如果您想读取超过 1 个字节,则需要在循环中执行此操作,因为read 始终可以处理少于请求的数量。

同样,write 也可以处理小于请求的大小(参见man 2 write):

RETURN VALUE

On success, the number of bytes written is returned (zero indicates nothing was written).  It is not an error  if  this
number  is  smaller than the number of bytes requested; this may happen for example because the disk device was filled.
See also NOTES.

On error, -1 is returned, and errno is set appropriately.

这里唯一的区别是当write返回0不是错误或文件结束指示符时,你应该重试写入。

您的代码几乎是正确的,因为它使用循环继续读取,直到没有更多字节可供读取(当read 返回0 时),但有两个问题:

  1. 您应该在read (rlen &lt; 0) 之后检查错误。
  2. 当您使用write 时,您还应该在那里添加一个循环,因为正如我刚才所说,即使write 也可以处理少于请求的字节数。

您的代码的正确版本是:

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

#define BUF_SIZE 256

int main(int argc, char *argv[])
{
    char buf[BUF_SIZE];
    ssize_t rlen, wlen, written;
    char from, to;
    int i;

    from = 'e';
    to = 'a';

    while (1) {
        rlen = read(0, buf, sizeof(buf));

        if (rlen < 0) {
            perror("read failed");
            return 1;
        } else if (rlen == 0) {
            return 0;
        }

        for (i = 0; i < rlen; i++) {
            if (buf[i] == from)
                buf[i] = to;
        }

        for (written = 0; written < rlen; written += wlen) {
            wlen = write(1, buf + written, rlen - written);

            if (wlen < 0) {
                perror("write failed");
                return 1;
            }
        }
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 2013-10-24
    • 1970-01-01
    • 2010-11-02
    • 2017-12-13
    • 1970-01-01
    • 2018-04-17
    • 2023-03-07
    • 1970-01-01
    • 2011-04-04
    相关资源
    最近更新 更多