C: Wieso gibt das Programm bei Eingabe eines Buchstaben oder etwas Unsinnigem den Schleifenkörper und dessen printf aus?


13.05.2023, 15:36

Hier wäre ein vollständiger Code(auf Wunsch):

#include <stdio.h>

#include <stdlib.h>

int main() {

    int zahl;

    char c;

    printf("Bitte geben Sie eine Zahl ein: ");

    while (scanf("%d%c", &zahl, &c) != 2 || c != '\n' || zahl < 1) {

        printf("Falsche Eingabe. Bitte geben Sie eine Zahl ein, die nicht kleiner als 1 ist.\n");

        while ((c = getchar()) != '\n' && c != EOF);

    }

    printf("Die eingegebene Zahl ist %d\n", zahl);

    return 0;

}

teehouse  13.05.2023, 15:31
Alle Variablen sind initialisiert, keine Sorge. Hier die Schleife:

Kompletter Code wäre trotzdem sinnvoll. Zumindest ein Sinnabschnitt, der in sich frei von Compilerfehlern ist.

Niklasson873 
Fragesteller
 13.05.2023, 15:37

Ja hab ich dir mal hinzugefügt. Und ich habe zumindest schonmal herausgefunden, dass es sich um die Zeite mit dem while((c = getchar()...) handeln muss.

2 Antworten

Sobald ich jedoch eine Zahl kleiner 1 eingebe,

... hast Du die ganze Eingabe gelesen. Trotzdem liest Du mit getchar() eine weitere vollständige Zeile ein, bevor Du das nächste scanf() ausführst.

Das Löschen der Eingabezeile ist nur sinnvoll, wenn keine Zahl eingelesen werden konnte oder hinter der Zahl noch etwas stand. Letzteres halte ich aber für fehl am Platz: Du willst eine Zahl, und wenn sie gelesen werden konnte, sollte alles in Ordnung sein. Was danach kommt, ist an dieser Stelle nicht relevant. Da soll sich die nächste Eingabe drum kümmern.

Auf der anderen Seite solltest du die Schleife bei feof(stdin) oder ferror(stdin) abbrechen. Sonst hast Du eine Endlosschleife.

Also, ich habe jetzt leider nicht so viel Zeit:

Bei mir scheint es zu laufen, wenn ich die eine Zeile ändere in:

while (c != '\n' && c != EOF);

Weiß nicht, ob das das ist, was du haben willst. Aber mal kurz ein paar Anregungen:

  1. Nutze den Debugger, um schrittweise von Zeile zu Zeile zu Springen und nicht einfach immer den kompletten Code ausführen.
  2. Achte genau darauf, was scanf() und getchar() machen. Vielleicht tun diese Funktionen mehr als du willst. Warten vielleicht beide auf einen Input des Users?
  3. Fasse Code sinnvoll zusammen. Meiner sieht jetzt so aus:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>


int
main ()
{


  int zahl;


  char c;


  printf ("Bitte geben Sie eine Zahl ein: ");


      int input;
      bool isInputTwo;
      bool isNewLine;
      bool isNumberLessThanOne;
  do
    {
      input = scanf ("%d%c", &zahl, &c);
      isInputTwo = input == 2;
      isNewLine = c == '\n';
      isNumberLessThanOne = zahl < 1;
      if (!isInputTwo || !isNewLine || isNumberLessThanOne)
	{
	  printf
	    ("Falsche Eingabe. Bitte geben Sie eine Zahl ein, die nicht kleiner als 1 ist.\n");


	}
      while (c != '\n' && c != EOF);
    }
  while (!isInputTwo || !isNewLine || isNumberLessThanOne);






  printf ("Die eingegebene Zahl ist %d\n", zahl);


  return 0;


}



Hab da noch einige Code-Wiederholungen drin. Den Type boll kannst du mit C99 nutzen, wenn du am Anfang ein "#include <stdbool.h>" machst.

Ich glaube bei mir läuft es so wie ich es geschrieben habe. Und der Code ist lesbarer. Sinnvolle Benennung von Variablen ist fast schon die halbe Miete.

Vielleicht kann dir ein C-Experte noch mehr sagen.

Sorry für die vielen leeren Zeilen im Code. Keine Ahnung warum der das so macht. Nutze bitte auch hier bei GuteFrage die Code-Formatierungsfunktion, wenn du Code postest.

Niklasson873 
Fragesteller
 13.05.2023, 16:02

Alles klar, ich danke dir schonmal für die Antwort und die Ausführlichkeit. Das mag wohl stimmen klar, ich hätte das nur gern mit einer While-Schleife gelöst. Du benutzt jetzt eine do-while-Schleif, was wohl sinnvoller ist und generell ist das ja ganz schön viel Code. Nicht schlimm. Ich gebe die Frage mal an einen Professor weiter und poste die Antwort dann hier. Das macht mich ganz schön wild bis hierher haha :)

0
teehouse  13.05.2023, 16:03
@Niklasson873

Ja, ich habe eben noch ergänzt, dass ich Code-Wiederholungen habe. Sicher geht das auch mit einer kopfgesteuerten Schleifen. Ist mir auf die schnelle nicht eingefallen wie.

0