instructions after scanf() call get called twice [

2019-08-22 14:18发布

问题:

This question already has an answer here:

  • scanf() leaves the new line char in the buffer 4 answers

The following program:

#include <stdio.h>
#include <pthread.h>

char input;

void *
dpy(void *args)
{
        printf("\n[input] = %c\n", input);
}

void *
read(void *args)
{
        pthread_t child;

        printf("Write whatever - press 'F' to end\n");

        do
        {
                scanf("%c", &input);
                printf("begin\n");
                pthread_create(&child, NULL, dpy, NULL);
                pthread_join(child, NULL);
                printf("end\n");
        }
        while (input!='F');

        printf("done\n");
}

void
main ()
{
        pthread_t parent;

        pthread_create(&parent, NULL, read, NULL);
        pthread_join(parent, NULL);
}
  1. reads characters from standard input and stops at the 'F' character, using the parent thread.
  2. prints the message [input] = .. for each character the user types, using the child thread.

Problem

each message having the following pattern:

begin .. end

gets displayed twice after scanf call (which is within the loop at the read routine), although it is supposed to wait for the next character input from the next scanf call.

Any thoughts?

回答1:

Apart from the problem of scanf() leaving newline, you have a couple of more minor issues.

  1. Thread functions' prototype require they return a pointer. So read() and child() must have return NULL; at the end (or other value if necessary - but I don't see you have that need here).

  2. void main() is a non-standard protype for main(). Use int main(void) or equivalent.

  3. You should also check the return values of pthread_* functions; they could fail!

Having a leading whitespace in scanf( scanf(" %c", &input);) ignores any numbers of whitespace in the input. Hence it'd consume the newline character left by the previous input. But in general, it's better to avoid scanf and prefer fgets() instead. See Why does everyone say not to use scanf? What should I use instead?