2016-12-02 5 views
0
#include<stdio.h> 
#include<stdlib.h> 

int main() 
{ 
    char *userInput; 
    userInput = (char*)malloc(sizeof(userInput)); 

    printf("Commands:\n"); 
    printf("\ta name - adds given name to list\n"); 
    printf("\tr name - removes given name from list\n"); 
    printf("\tp  - prints out list\n"); 
    printf("\te  - exits\n"); 

    printf("\n\nEnter a command: "); 
    scanf("%s\n",userInput); 
    printf("\nThe user input was: %s\n", userInput); 

    return 0; 
} 

kompilieren ich den Code „gcc -std = gnu99 -m32 -Wall -g -o Namensliste namelist.c“ , wenn ich starten Sie die ausführbare alle ersten printf angezeigt und ich prompt auf eine Eingabe. Jedes Mal, wenn ich einen Eingang und drücken Sie die Eingabetaste eingeben, ich habe nicht den nächsten printf auffordern, bis ich in einen anderen Eingang setzen.Warum pausiert mein Programm nach der Verwendung von scanf?

This is what is looks like when I run the program

+0

Verwenden Sie den 'gdb' Debugger Ihr Programm Schritt für Schritt ausgeführt werden. –

+1

Willkommen bei Stack Overflow! [Bitte lesen Sie die Diskussion darüber, warum der Rückgabewert von 'malloc()' und die Familie in 'C' nicht umgewandelt werden soll.] (Http://stackoverflow.com/q/605845/2173917). –

+2

Hinweis: '\ n' ist für Wagenrücklauf. Sehen Sie in https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm ein '\ n'? –

Antwort

0

einfach die „\ n“ nehmen in Ihrem

scanf("%s\n",userInput) 
+0

Omg vielen Dank das hat mich verrückt gemacht – Programmer

+0

Sie haben dann einen Pufferüberlauf für jede Eingabe von mehr als 4 Bytes, z. 'foobar' –

+0

@BasileStarynkevitch Ich glaube, Pufferüberlauf tritt bei Eingabe mehr als 3 Zeichen (letztes Zeichen für' \ 0'). Das ist: 'malloc (sizeof (char *)) - 1 'um genau zu sein. – babon

0

Lesen Sie sorgfältigscanf(3). Beachten Sie, dass Sie mit gcc -m32sizeof(userInput) gleich 4 haben (die Größe aller Zeiger ist gleich; ohne die -m32 wäre es 8). Also, wenn der Benutzer etwas wie working (oder eine Eingabe von vier oder mehr Zeichen, nicht nur einen Buchstaben wie a) eingibt, haben Sie undefined behavior (wegen einer buffer overflow) und das ist wirklich bad. Sie sollten wahrscheinlich stattdessen verwenden (oder vielleicht sogar readline(3)), z.

char* userInput=NULL; 
size_t sizeInput= 0; 
printf("Commands:\n"); 
/// put your other printfs here, then 
ssize_t lengthInput = getline(&userInput, &sizeInput, stdin); 
if (lengthInput < 0 || userInput==NULL) 
    { perror("input error"); exit(EXIT_NULL); }; 

Jetzt haben Sie die gesamte typisierten Linie in userInput (einschließlich des abschließenden Newline), und Sie wissen, dass seine Länge lengthInput ist. Sie können parse diese Zeile, vielleicht mit sscanf(3) (Hinweis: Verwenden Sie die Anzahl der Rücksendungen, und verwenden Sie %n) oder nur mit anderen Techniken (einige strcmp oder strtok(3) ...). Wenn Sie fertig sind, sollten Sie free(userInput).

Beachten Sie, dass scanf (oder sscanf) keinen Speicher für geparste Daten zuweisen, außer Sie verwenden %ms (was wahrscheinlich POSIX-spezifisch ist). Mit %s erwartet es immer einige feste Länge Puffer und für eine Array Puffer erklärt char buf[64]; Sie geben besser die Größe mit %63s; BTW, sollten Sie immer die Ergebnisanzahl von scanf testen. So könnte Code, den Sie (nach dem oben)

char nambuf[64]; 
if (sscanf(userInput, "a %63s", nambuf)==1) { 
// use nambuf to add it 
} 
else if (sscanf(userInput, "r %63s", nambuf)==1) { 
// use nambuf to remove it 
} 

(aber die oben ist ein bisschen dumm, lesen wir eine beliebige Größe Linie, sondern Prozess nambuf von höchstens 63 Bytes). Sie könnten einfach scanf wie if (scanf("a %63s", nambuf)==1) ohne userInput verwenden.

Alternativ können Sie den Linux-spezifische %as oder besser verwenden die POSIX-spezifische %ms wie:

char* nameptr=NULL; 
if (scanf("a %ms", &nameptr)==1) { 

dann, dass eine erfolgreiche scanfmalloc -ed haben würde und gefüllt nameptr und Sie sollten später free(nameptr). Wenn Sie nur Kleinbuchstaben annehmen möchten etwas betrachten Codierung wie if (scanf("a %m[a-z]", &nameptr)==1) etc ...

1

Während ein Zeichen (char) oder Zeichensatz (char*) kommen aus stdin mit scanf ähnlicher Funktion \n (Ergebnis der Enter-Taste drücken) bleibt im Puffer.Also vor der nächsten Eingabe sollte das Programm reinigen, dass \n sowie alle anderen Unordnung, die in den Eingabepuffer (z. B. nach falschen Zahlen, wie - scanf12 und asw\n im Puffer) sein kann.

Betrachten Sie das folgende Beispiel und darauf achten, dass ich clnInpBuf() zu verwenden empfehlen:

#include <stdio.h> 

void clnInpBuf() 
{ 
    char c; 
    while ((c = getchar()) != '\n' && c != EOF); 
} 

int main(void) 
{ 
    char str[10]; 
    char ch; 
    scanf("%c", &ch); 
    fflush(stdin); // in some cases that works for input stream 
        // (but fflush is better to use only for output streams) 
    scanf("%9s", str); 
    clnInpBuf(); // this works always 
    printf("char was %c.\n", ch); 
    printf("string was %s.\n", str); 
} 

UPDATE:

Vorlage für Ihren "Befehlsprozessor" kann sein:

int main(void) 
{ 
    char name[21]; 
    char command; 
    while (1) 
    { 
     scanf("%c", &command); 
     clnInpBuf(); 
     switch (command) 
     { 
     case 'a': 
     case 'r': scanf("%20s", name); 
        clnInpBuf(); 
        printf("Command was:\n%c %s\n", command, name); // if ('a'==command) addRecord(name); else removeRecord(name); 
        break; 
     case 'p': // TODO: add output 
        break; 
     case 'e': return 0; 
        break; // this is not realy needed 
     default: 
        printf("Wrong command\n"); 
     } 

    } 
} 
+0

'fflush (stdin)' ist * falsch *, man kann nur einen * Ausgabestrom * oder 'NULL'' flackern –

+0

@BasileStarynkevitch Ja, du hast Recht !! ... Aber ich habe tatsächlich geschrieben "in einigen Fällen fflush) funktioniert "und" Ich empfehle, clnInpBuf() " – VolAnd

0

Diese Anweisung weist 4 Byte Daten zu, da Benutzereingabe Zeiger ist. userInput = (char *) malloc (sizeof (userInput));

Wie aus der obigen Antwort hervorgeht, führt dies zu einem Pufferüberlauf, wenn die Zeichenfolgengröße mehr als 3 Byte beträgt.

auch würde ich fgets() über Scanf vorschlagen, wenn eine Zeichenfolge

Beispielcode lesen -

#include <stdio.h> 
    #include <stdlib.h> 


    int main() { 
     // your code goes here 
    char *userinput = (char *)malloc(100); 
    fgets(userinput,100,stdin); 
    printf("%s",userinput); 
    return 0; 
} 
+0

zu verwenden. Die einzige zusätzliche Information, die Sie geben, ist der Vorschlag,' fgets' zu verwenden. Aber dann müssen Sie mehr Code geben. –

+0

hat einen Beispielcode für fgets hinzugefügt – hariudkmr