getchar non si ferma quando si usa scanf

Ho difficoltà a capire getchar() . Nel seguente programma getchar funziona come previsto:

 #include  int main() { printf("Type Enter to continue..."); getchar(); return 0; } 

Tuttavia, nel seguente programma, getchar non crea un ritardo e il programma termina:

 #include  int main() { char command[100]; scanf("%s", command ); printf("Type Enter to continue..."); getchar(); return 0; } 

Ho la seguente soluzione alternativa, che funziona, ma non capisco perché:

 #include  int main() { char command[100]; int i; scanf("%s", command ); printf("Type Enter to continue..."); while ( getchar() != '\n') { i=0; } getchar(); return 0; } 

Quindi le mie domande sono:
1. Che cosa fa scanf ? Perché scanf fa questo?
2. Perché il mio lavoro è in funzione?
3. Qual è un buon modo per emulare il seguente codice Python:

 raw_input("Type Enter to continue") 

    L’input viene inviato al programma solo dopo aver digitato una nuova riga, ma

     scanf("%s", command ); 

    lascia la nuova riga nel buffer di input, poiché il formato %s (1) si interrompe quando viene rilevato il primo carattere di spazio getchar() dopo alcuni spazi non bianchi, getchar() restituisce immediatamente tale nuova riga e non è necessario attendere ulteriori input.

    La soluzione alternativa funziona perché cancella la nuova riga dal buffer di input prima di chiamare getchar() .

    Per emulare il comportamento, cancellare il buffer di input prima di stampare il messaggio,

     scanf("%s", command); int c; do { c = getchar(); }while(c != '\n' && c != EOF); if (c == EOF) { // input stream ended, do something about it, exit perhaps } else { printf("Type Enter to continue\n"); getchar(); } 

    (1) Si noti che l’utilizzo di %s in scanf è molto pericoloso, si dovrebbe limitare l’input a ciò che il buffer può contenere con una larghezza di campo, scanf("%99s", command) leggerà al massimo 99 ( sizeof(command) - 1) ) caratteri in command , lasciando spazio per lo 0-terminator.

    Lo spazio bianco è un delimitatore per l’identificatore di formato 5y3% s, e newline è considerato come spazio bianco, quindi rimane bufferizzato. L’input della console è normalmente orientato alla linea, quindi una chiamata successiva a getchar () verrà restituita immediatamente perché una “riga” rimane memorizzata nel buffer.

     scanf("%s", command ); while( getchar() != '\n' ){ /* flush to end of input line */ } 

    Allo stesso modo se si usa getchar () o% c per ottenere un singolo carattere normalmente si deve svuotare la linea, ma in questo caso il carattere inserito può essere di per sé una newline quindi è necessario una soluzione leggermente diversa:

     scanf("%c", ch ); while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ } 

    allo stesso modo per getchar ():

     ch = getchar(); while( ch != '\n' && getchar() != '\n' ){ /* flush to end of input line */ } 

    La cosa sensata da fare ovviamente è avvolgere queste soluzioni in funzioni di input specializzate indipendenti che è ansible riutilizzare e utilizzare anche come luogo per inserire la convalida dell’input comune e il codice di controllo degli errori (come nella risposta di Daniel Fischer che controlla sensibilmente EOF – normalmente si vorrebbe evitare di dover duplicare tali controlli e la gestione degli errori ovunque).

    Preferirei usare prima fgets e quindi usare sscanf per analizzare l’input. Ho fatto cose del genere per molto tempo e il comportamento è stato più prevedibile rispetto all’utilizzo di scanf semplice.

    Bene, ho qualcosa di più semplice: aggiungi un altro getchar() … problema risolto !!

    dopo aver preso l’input del comando, lavare lo stdin.

     fflush(stdin); 

    ma il flushing di un stream di input comporta un comportamento indefinito (sebbene la libreria C di Microsoft definisca il comportamento come un’estensione).