如何使用相同的缓冲区写入两个不同的地方? (C系统调用)

时间:2018-01-31 16:18:09

标签: c io buffer system-calls tee

我应该使用'-a'标志的选项来实现Unix'tee'命令,该标志会将输入附加到EOF而不是覆盖它。问题是我只能使用C系统调用I / O.到目前为止,我已经能够实现除多输出之外的所有内容。

在我的while循环中,我有两个不同的行,一个写入文件,另一个写入stdout。如果我评论一个,或者将一个放在另一个之前,那就有效,但保持两者都没有。只有我先调用的写函数才有效。我假设,因为如果我理解正确,它会清空缓冲区。

如何写出我输入到stdin,stdout和文件的任何内容?

#include "csapp.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {

   int aflag = 0;
   int n_char = 0;
   int c,fd;
   char *path;
   char buf;

   opterr = 0;

   // getopt is looking for flags with dashes
   while((c = getopt(argc, argv, "a")) != -1)
      switch (c)
      {
         // assign the aflag value to 1, so we know that arg was applied
         case 'a':
            aflag = 1;
            break;
         case '?':
            if (isprint (optopt))
               fprintf(stderr, "Unknown option \\x%x'.\n",optopt);
            return 1;
         default:
            abort();
      }

   // if the -a flag was provided, we must append, if not overwrite the file
   // by default if the file exists.
   if(aflag == 1) {
      path = argv[2];
      fd = open(path,O_WRONLY|O_APPEND,0);
   } else {
      path = argv[1];
      fd = open(path,O_WRONLY,0);
   }

   // While not EOF, right to stdout and file
   while((n_char=read(STDIN_FILENO, &buf,1)) != 0)
      n_char=write(fd, &buf, 1);
      write(STDOUT_FILENO,&buf,1);
   close(fd);

   return 0;
}

1 个答案:

答案 0 :(得分:0)

您的while循环没有{}。因此,它只考虑循环体中的第一个语句:

   while((n_char=read(STDIN_FILENO, &buf,1)) != 0)
      n_char=write(fd, &buf, 1);
      write(STDOUT_FILENO,&buf,1);  <===== this statement is out of loop body

为循环体中的语句块添加{}

   while((n_char=read(STDIN_FILENO, &buf,1)) != 0) {
      n_char=write(fd, &buf, 1);
      write(STDOUT_FILENO,&buf,1);
   }

其他

作为良好编程习惯的一部分,您还应该在程序中使用系统调用(&#39; s)的返回值,例如write(),并确保正确进行错误处理。< / p>

write

  

出错时,返回-1,并正确设置errno