不了解stdout语义

时间:2012-01-11 19:37:30

标签: c linux redirect cat

这里有新手!

下面我的程序试图在Linux中执行(一点点)cat命令。

  1. 如果没有提供参数,则它从用户接收输入并在屏幕上打印。(对于非常简单的场景,输入缓冲区假设为10)..

  2. 如果我传递多个参数,它正在工作......即。它逐个显示不同文件的内容 - 编程..

  3. - 现在重点是当我在shell上发出命令时:

      

    ./ mycat abc.txt>测试

    其中mycat是我的程序名称,abc.txt是必需的文件,我将其重定向到新的文件测试。 我无法理解的奇怪的部分是,重定向后,如果我查看文件测试,它首先显示文件abc.txt中的数据然后我的printf函数在c程序中而不是显示printfs然后那么数据。这是什么原因?

    int main(int argc,char *argv[])
    {
        char buf[10]; 
        int x,read_bytes,i,fd;
        read_bytes=1;
        char read_buf[1024*1024];
    
        for(i=0;i<argc;i++)
             printf("you entered  %s\n",argv[i]); //this printf
    
        switch(argc)
        {
        case 1:
             x=read(0,buf,sizeof(buf));
             write(1,buf,x);
             break;
    
        default:
             for(i=1;i<argc;i++)
             {
                 printf("showing the %dth file\n\n",i);
                 fd=open(argv[i], O_RDONLY);
                 if(fd==-1)
                 {
                     perror("no file opened for such name");
                     exit(1);
                 }
                 while(read_bytes!=0)
                 {
                     read_bytes=read(fd,read_buf,sizeof(read_buf));
                     if(read_bytes==-1)
                     {
                         perror("not able to read\n");
                         exit(2);
                     }
                     write(1,read_buf,read_bytes);
                 }
                 read_bytes=1;
                 close(fd);
             }
             break;
         }
    
         return 0;
    }
    

3 个答案:

答案 0 :(得分:4)

printf也打印到stdout,其文件描述符为1,因此您将printf行写入与文件内容相同的输出。

您可能更喜欢将诊断信息写入单独的输出,例如stderr

fprintf(stderr, "Hello world.\n");

答案 1 :(得分:2)

其他答案是正确的,但似乎没有解释问题 printfwrite(1)都写入stdout。但是printf是缓冲的,而write则不是。{ 因此,使用printf编写的数据首先会转到某个缓冲区,并且只有在操作系统选择时才会写入。但是,write写的数据直接转到文件中 结果是所有内容都打印出来,但不是按照您想要的顺序打印。由printf打印的数据可以在稍后write写入的数据之后写入。

答案 2 :(得分:1)

请在每个fflush(stdout)后使用printf,以便刷新stdout缓冲区。执行此操作后,printfs将按照代码顺序显示。

这是修改后的代码。

int main(int argc,char *argv[])
{
    char buf[10]; 
    int x,read_bytes,i,fd;
    read_bytes=1;
    char read_buf[1024*1024];

    for(i=0;i<argc;i++)
        printf("you entered  %s\n",argv[i]); //this printf
    fflush(stdout);
    switch(argc)
    {
     case 1:
          x=read(0,buf,sizeof(buf));
          write(1,buf,x);
          break;

     default:
          for(i=1;i<argc;i++)
          {
              printf("showing the %dth file\n\n",i);
              fflush(stdout);
              fd=open(argv[i], O_RDONLY);
              if(fd==-1)
              {
                 perror("no file opened for such name");
                 exit(1);
              }
              while(read_bytes!=0)
              {
                 read_bytes=read(fd,read_buf,sizeof(read_buf));
                 if(read_bytes==-1)
                 {
                     perror("not able to read\n");
                     exit(2);
                 }
                 write(1,read_buf,read_bytes);
             }
             read_bytes=1;
             close(fd);
         }
         break;
     }

     return 0;
}