Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

not understanding stdout semantics

A newbie here!

My program below is trying to act like (a little) cat command in Linux.

  1. if no arguments is supplied then it takes input from user and prints on screen.(input buffer is assumed 10 for a very simple scenario)..

  2. if i pass multiple arguments it is working..i.e. it is showing the contents of different files one by one -as programmed..

--now the point is that when i give command on shell like:

./mycat abc.txt > test

where mycat is my program name and abc.txt is the required file and i am redirecting it to a new file test. Strange part which I am not able to understand is that after redirection if i look into the file test, it shows the data from the file abc.txt first then my printf functions in the c program instead of showing the printfs and THEN the data. What is the reason for this?

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;
}
like image 467
saurabh Avatar asked Jan 20 '26 22:01

saurabh


2 Answers

printf also prints to stdout, whose file descriptor is 1, so you're writing the printf line to the same output as the file contents.

You might prefer writing diagnostics to a separate output, such as stderr:

fprintf(stderr, "Hello world.\n");
like image 122
Kerrek SB Avatar answered Jan 22 '26 12:01

Kerrek SB


Other answers are correct, but don't seem to explain the problem.
Both printf and write(1) write to stdout. But printf is buffered, while write isn't.
So data you write with printf goes first to some buffer, and is really written only when the OS chooses to. Data written by write, however, goes directly to the file.
The result is that everything is printed, but not in the order you want. Data printed by printf can be written after data written by a later write.

like image 31
ugoren Avatar answered Jan 22 '26 13:01

ugoren