Why is there an extra percent sign after the output?

Viewed 2448

I'm learning fork() function under linux recently. I wrote a program.

#include<stdio.h>
int main(){
    int p1, p2;
    while((p1 = fork()) == -1);
    if(p1 == 0)
        printf("b");
    else{
        while((p2 = fork()) == -1);
        if(p2 == 0)
            printf("c");
        else
            printf("a");
    }
}

After I compiled and run it, I got a unexpected percent sign.

enter image description here

But if I add \n after those letters, the percent sign disappears.

enter image description here

Is there anyone knows the reason?

And I have another question. Every time I reran the program, I got the same answer. It always shows "acb". The order is always the same. Why?

2 Answers

Your shell (zsh) added it to indicate the output did not end with a newline character.

To get rid of it, just end your output with a \n.

As to the other question, it's not deterministic. If you ran it elsewhere or enough times you might get different results. But it's an illustration of why synchronization problems can be so hard to find, because things can seem to run the same (almost) all the time.

the following proposed code:

  1. correctly checks the returned value from fork()
  2. correctly includes the necessary header files
  3. correctly waits for the child processes to exit before the parent process exits
  4. still does not terminate output strings with '\n' so (in this case) the output is not displayed on the terminal until after the process exits.
  5. uses the proper typing for pid variables
  6. uses one of the two valid signatures for main()

And now the proposed code:

#include <stdio.h>     // printf(), perror()
#include <stdlib.h>    // exit(), EXIT_FAILURE, EXIT_SUCCESS
#include <sys/types.h> // pid_t
#include <unistd.h>    // fork()
#include <sys/wait.h>  // wait()

int main( void )
{
    pid_t p1;
    pid_t p2;

    p1 = fork();
    switch( p1 )
    {
        case -1:
            perror( "first fork failed" );
            exit( EXIT_FAILURE );
            break;

        case 0:  // child 1
            printf("child 1");
            exit( EXIT_SUCCESS );
            break;

        default:  // parent
            p2 = fork();
            switch( p2 )
            {
                case -1:
                    perror( "second fork failed" );
                    exit( EXIT_FAILURE );
                    break;

                case 0: // child 2
                    printf("child 2");
                    exit( EXIT_SUCCESS );
                    break;

                default:
                    printf("parent");
                    while( wait( NULL ) != -1 );
                    break;
            }  // end switch 2
    } // end switch 1
}

a typical run of the code results in:

child 2child 1parent
Related