Search code examples
cubuntuvirtual-machine

Weird terminal display glitch in c, Ubuntu


When I run the first code it with "\n" at the end of every print statement it gives me the expected output which is in case of num == 35

The generated sequence:
35
106
53
160... 

code to generate collatz sequence:

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>

int main(int argc, char* argv[])
{
    int fd[2], fd1[2], num = atoi(argv[1]), id = getpid();
    
    printf("\nRecieved number: %d\n", num);

    if(num > 0)
    {
        printf("The generated sequence: \n");
        
        while(num > 1)
        {   
            pipe(fd);
            pipe(fd1);

            if(fork()) //parent process
            {
                printf("%d \n", num);
                int n;
                close(fd[0]); //closing read end..
                close(fd1[1]); //closing write end..

                write(fd[1], &num, sizeof(num));
                wait(NULL);
                read(fd1[0], &n, sizeof(n));

                num = n;

                close(fd[1]);
                close(fd1[0]);

                if(num == 1) {
                    printf("1\n");
                    exit(0);
                }
            }

            else    //child process
            {
                int n;
                close(fd[1]); //closing write end..
                close(fd1[0]); //closing read end..

                read(fd[0], &n, sizeof(n));

                if(n%2 == 0)
                    n /= 2;
                
                else   
                    n = 3*n+1;

                write(fd1[1], &n, sizeof(n));

                close(fd1[1]);
                close(fd[0]);
                exit(0);
            }
        }
    }

    else {
        printf("\nERROR: number should be positive!!\n");
        exit(1);
    }

    return 0;
}

...But the problem is if I change the printing line

printf("%d \n", num);

to

printf("%d, ", num);

my output will have repetitions i.e.

it will print: with n=35

sequence: 35 sequence: 35, 106 sequence: 35, 106, 53 sequence: 35, 106, 53, 160...

Although printing on new line fixes the repetition problem, I don't want to print every number of sequence on new line.


Solution

  • Without a newline character, the output remains in the program‘s buffer. When the program forks, the buffer is duplicated along with the rest of the program. Eventually, both the parent and the child write more output, including what was in the buffer. So the output appears multiple times.

    You can eliminate this duplication of the buffer contents by flushing the buffer forking. Put fflush(stdout); immediately before if (fork()). Flushing the buffer (which is inside the executing process) writes its contents to the stream (which is outside the executing process) and empties it.