2 x Aufforderung fuer 1 x Benutzereingabe



  • Es handelt sich um folgendes Programm:

    #include <stdio.h>
    #include <stdlib.h>
    
    void printMenu(void) {
    	printf("a - add a new edge\n\
    r - remove an edge\n\
    p - print nodes\n\
    q - quit\n\
    h - print this help\n");
    	fflush(stdout);
    }
    
    int main(int argc, char *argv[]) {
    	int nodeNum;
    	char choise;
    
    	printf("How many nodes should be manages: ");
    	scanf("%d", &nodeNum);
    
    	if (nodeNum <= 0)
    		exit(-1);
    
    	for (choise = 'h'; choise != 'q';) {
    		switch (choise) {
    			case 'a':
    			case 'r':
    			case 'p':
    				break;
    			case 'h':
    				printMenu();
    				break;
    			case 'q':
    			default:
    				choise = 'q';
    		}
    
    		printf("Please select: ");
    		fflush(stdout);
    		scanf("%c", &choise);
    		/*choise = getchar();*/
    	}
    
    	return 0;
    }
    

    Wenn ich das versuche Auszufuehren werde ich zuerst nach der Anzahl der Elemente gefragt. OK, dann dann geh ich in die Schleife rein und werd nach der Auswahl gefragt. Urgs. Ich werd da 2mal gefragt.
    Das ganze sieht dann so aus:

    How many nodes should be manages: 10
    a - add a new node
    r - remove a node
    p - print nodes
    q - quit
    h - print this help
    Please select: Please select: q

    Das ganze fflush vor und hinter/von stdin von stdout bringt nichts. Hab's auch mit getchar versucht, auch nichts ...

    Meine Frage: warum?



  • Weil die Schleife zweimal durchlaufen wird, erst beim zweiten mal wird auf die Eingabe gewartet, Grund:

    Weil das erste scanf (scanf("%d", &nodeNum);) das '\n' Zeichen im Puffer lässt, gehört ja nicht zu einem Integer Wert. Dieses wird in der Schleife von scanf gelesen, weil ja noch etwas im Puffer ist, gehört ja zu einem char. Dann erst ist der Puffer leer und das Programm wartet auf die Eingabe.



  • Hm,

    int main(int argc, char *argv[]) {
    	int nodeNum;
    	char choise, newline;
    
    	printf("How many nodes should be manages: ");
    	scanf("%d%c", &nodeNum, &newline);
    	fflush(stdin);
    
    	if (nodeNum <= 0)
    		exit(-1);
    
    	init(nodeNum); 
    
    	for (choise = 'h'; choise != 'q';) {
    		switch (choise) {
    			case 'a':
    				userAddEdge();
    				break;
    			case 'r':
    				userRemoveEdge();
    				break;
    			case 'p':
    				printAll();
    				break;
    			case 'h':
    				printMenu();
    				break;
    			case 'q':
    			default:
    				choise = 'q';
    		}
    
    		printf("Please select: ");
    		scanf("%c%c", &choise, &newline);
    		fflush(stdin);
    	}
    	destroy();
    
    	return 0;
    }
    

    So, jetzt fang ich das \n ab, jetzt funktioniert die Benutzereingabe nicht mehr korrekt. Hab alle Kombinationen durchprobiert (mit fflush, ohne fflush, mit zweiten newline und auch ohne)...
    bin verwirrt



  • scanf("%d%c", &nodeNum, &newline);
    

    Das entfernt nicht zuverlässig das '\n', es könnte jemand
    z.B. 1a eintippen dann bleibt das '\n' im Puffer, es könnte jemand
    1ab eintippen, dann bleibt "b\n" im Puffer, etc.

    fflush(stdin);
    

    Das auch nicht, weil microsoftspezifisch ( Guckst du FAQ ).

    Eingabepuffer kriegst du nach einem scanf Aufruf leer mit folgender guckst du Funktion:

    void cb() // clear buffer
    {
    	int c;
    	while ( (c = getchar()) != '\n' && c != EOF )
    	{} // mache nixe
    }
    

    Damit ist aber deine Eingabe immer noch nicht bombensicher, muss sie ja vllt. auch nicht sein, k.A.
    Mir ist es noch nicht gelungen mit scanf eine 100% bombensichere (DAU sichere :D) Eingabe hinzukriegen, die einen int/unsigned int einliest.
    Dann evtl. lieber die Eingabe ab in ein char Array einlesen und dieses
    checken.
    Gruß,
    B.B.


Log in to reply