【问题标题】:Why am I not getting an output when reading from a file descriptor?为什么从文件描述符读取时没有得到输出?
【发布时间】:2021-09-14 00:47:41
【问题描述】:

我正在尝试从文件中读取并打印出来供用户阅读。我的任务类似于 UNIX 'cat' 命令,但我的代码不打印任何内容。

#include<unistd.h>
#include<fcntl.h>
#include<stdio.h> //for printf

int main(int argc, char *argv[])
{  
  int fd;
  char buffer;

  if(argc==1)
    fd=open(argv[1],O_RDONLY);
  else
    if (fd=open(argv[1],O_RDONLY) ==0){
    printf("Error opening");
    return(0);
  }

  while((read(fd,&buffer,1)) != -1){
     read(fd,&buffer,1);
     write(STDOUT_FILENO,buffer, 1);

  }
    return(0);
}

【问题讨论】:

  • 为什么要打开文件两次?
  • 这有很多问题,如果您打开警告,您的编译器会告诉您其中一些问题(-Wall -Wextra 是 gcc 和 clang 的良好开端)。
  • if(argc==1) fd=open(argv[1],O_RDONLY); 如果argc &lt; 2 访问argv[1] 是不合法的。
  • @RetiredNinja 如果argc 为1,则argv[1] 保证为空指针。当然,您不应该将其传递给open,但仅访问它是合法的。
  • 在执行read/write 时,缓冲区大小为 1 有点慢。每个调用都是一个内核 用户空间上下文切换,具有复杂的错误处理。建议使用更大的缓冲区和更复杂的错误处理。幸运的是,libc 已经提供了易于使用的缓冲区。使用fopenfclose的文件流,然后可以使用fgetcfputc进行单字节IO。

标签: c linux unix


【解决方案1】:

由于优先级问题,您从错误的 FD 中读取。 if (fd=open(argv[1],O_RDONLY) ==0) 被解析为 if (fd=(open(argv[1],O_RDONLY) ==0))。您希望它被解析为 if ((fd=open(argv[1],O_RDONLY)) ==0),所以写下来。

其他问题:

  • 0 是合法的 FD。您应该检查 -1,而不是查看 open 是否失败。
  • 如果argc 是1,那么argv[1] 是一个空指针,你不应该尝试open
  • 连续两次而不是一次调用 read 意味着您将丢弃所有其他角色。
  • write 需要一个指针,所以像使用 read 一样传递它 &amp;buffer。记住不是printf
  • read 可以在您到达 EOF 时返回 0,现在这会将您的程序发送到打印最终字符的无限循环中。

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多