tastatureingabe - zahlen einlesen bis ENTER



  • guten tag
    es sollen zahlen per tastatur eingegeben und vom programm eingelesen werden, drück der benutzer ENTER ohne etwas eingegeben zu haben, wird die eingabe beendet.
    ist so etwas machbar? welche funktionen brauche ich dazu?
    danke schonmal
    :=)



  • Klar ist das machbar.

    Eine Möglichkeit wäre scanf zu benutzen.

    Oder du liest eine ganze Zeile ein und wandelst den Text dann mit strtol oder strtod um.


  • Mod

    DirkB schrieb:

    Eine Möglichkeit wäre scanf zu benutzen.

    Eigentlich nicht. Die dumme Aufgabenstellung (die vermutlich besonders anfängerfreundlich sein soll 🙄 ) macht alles kaputt. Bis Eingabeende (oder Fehler) wäre ja einfach mit scanf. Aber scanf überliest in der einfachsten Fassung auch Whitespaces wie den Zeilenumbruch.

    Oder du liest eine ganze Zeile ein und wandelst den Text dann mit strtol oder strtod um.

    Ich fürchte, dies ist die Lösung 😞 . Oder ein cleverer scanf-Formatstring, wobei mir für diese spezielle Aufgabe spontan keiner einfällt - müsste ich erst austüfteln.



  • prominent schrieb:

    ...drück der benutzer ENTER ohne etwas eingegeben zu haben, wird die eingabe beendet.
    ist so etwas machbar? welche funktionen brauche ich dazu?
    danke schonmal
    :=)

    Guck dir mit der Funktion getchar das erste Zeichen der Eingabe an, ist es ein \n, so steigst du aus der Schleife zum Einlesen aus, ist es kein \n, dann schubst du es mit ungetc zurück in die Standardeingabe(Eingabepuffer/Eingabestrom).
    Ein anschließender Aufruf von scanf frisst dann alles, was zum Formatstring passt ( in deinem Fall dann double, int, etc ).

    Hast du schon mit scanf gearbeitet? Wenn nicht, dann gibt es da noch einiges zu beachten, wenn z.B. 123X eingegeben wird, dann liefert scanf
    im Falle eines korrekten Formatstrings eine 1, aber das X\n bleibt in der Eingabe unverarbeitet, diese Zeichen müsstest du vor dem nächsten Einlesen entfernen,

    z.B. via

    void clear_stdin ( void )
    {
    	if ( EOF != fscanf ( stdin, "%*[^\n]" ))
    		getchar();
    }
    

    oder

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

    sonst kann dein Programm in einer Endlosschleife hängen bleiben.



  • Ich hatte ja auf einen Dialog mit dem TO gehofft, damit er die Vor-/Nachteile der unterschiedlichen Möglichkeiten versteht.



  • Zahlen kann man nicht einlesen, nur Zeichen, die als Ziffern interpretieren (lassen) und daraus Zahlen basteln (lassen).



  • CJosef schrieb:

    Guck dir mit der Funktion getchar das erste Zeichen der Eingabe an, ist es ein \n, so steigst du aus der Schleife zum Einlesen aus, ist es kein \n, dann schubst du es mit ungetc zurück in die Standardeingabe(Eingabepuffer/Eingabestrom).
    Ein anschließender Aufruf von scanf frisst dann alles, was zum Formatstring passt ( in deinem Fall dann double, int, etc ).

    damit hab ich es hinbekommen, danke.

    DirkB schrieb:

    Ich hatte ja auf einen Dialog mit dem TO gehofft, damit er die Vor-/Nachteile der unterschiedlichen Möglichkeiten versteht.

    welche wären das?



  • Z.B. dass scanf Whitespace überliest und Zeichen die nicht zum Formatspecifier passen im Eingabestrom belässt.

    Das kann bei Fehleingaben zu merkwürdigem Programmverhalten führen, wenn man das nicht berücksichtigt.

    Oder beim Zusammenspiel mit fgets, wenn vorher ein scanf das '\n' stehen läßt.

    Wenn man das Alles weiß, kann man damit umgehen.



  • DirkB schrieb:

    Z.B. dass scanf Whitespace überliest und Zeichen die nicht zum Formatspecifier passen im Eingabestrom belässt.

    Das kann bei Fehleingaben zu merkwürdigem Programmverhalten führen, wenn man das nicht berücksichtigt.

    Oder beim Zusammenspiel mit fgets, wenn vorher ein scanf das '\n' stehen läßt.

    Wenn man das Alles weiß, kann man damit umgehen.

    dann ist es egal ob man scanf oder fgets/sscanf benutzt(unter berücksichtigung der von dir genannten unterschiede)?
    weil für fgets brauch ich ja ein array und für scanf nicht.
    obwohl intern wird scanf auch mit einem array arbeiten? keine ahnung... wenn ja, dann wärs wohl egal.

    ich habe meine eingabe soweit fertig, verbesserungsvorschläge sind willkommen.

    enum ArraySize {arrsize = 20};
    
    int main(void)
    {
    	int c;
    	unsigned n = 0;
    	double number;
    	double numbers[arrsize] = {0};
    
    	printf("Geben Sie maximal %u Zahlen ein:\n", arrsize);
    
    	while ((c = getchar()) != '\n' && n < arrsize) {
    		if (EOF == ungetc(c, stdin)) {
    			perror("ungetc");
    			break;
    		} else if (1 != scanf("%lf", &number)) {
    			clear_stdin();
    			puts("Ungueltige Eingabe, erneut versuchen!");
    		} else if (getchar() != '\n') {
    			clear_stdin();
    			puts("Ungueltige Zeichen in der Eingabe, erneut versuchen!");
    		} else numbers[n++] = number;
    
    		if ( n >= arrsize ) {
    			puts("Die maximale Anzahl der eingegebenen Zahlen wurde erreicht!");
    			break;
    		} 
    	}
    	printf("Anzahl eingegebener Zahlen: %u\n", n);
    	puts("Druecken Sie ENTER, um das Programm zu beenden.");
    	getchar();
    	return 0;	
    }
    

    danke@ cjosef & dirkb!



  • zwischen die zeilen 18/19, 21/22 könnte man eventuell noch ein

    continue;
    

    einfügen.
    ob das aber so der bringer wäre weiß ich nicht.



  • Man kann den Gebrauch von getchar/scanf auch übertreiben, so wie hier.
    Üblicherweise kapselt man in C die Funktionalitäten in Funktionen, hier also
    - Einlesen (einer Zeichenfolge) aus stdin
    - Interpretieren/Auswerten
    und für sowas gibt es fgets mit sscanf, also z.B.

    char s[100];
    ...
    while( n<20 && fgets(s,100,stdin) && *s!='\n' && strchr(s,'\n') )
      n+=sscanf(s,"%lf",&numbers[n])==1;
    


  • Wutz schrieb:

    Man kann den Gebrauch von getchar/scanf auch übertreiben, so wie hier.

    Was ist hier übertrieben? Begründung?


Anmelden zum Antworten