Fehlerabfrage

Studentin2009

Grünschnabel
Hallo!

Ich habe folgendes Problem:
Ich möchte kontrollieren, ob die Eingabe die gemacht wurde wirklich
- eine Zahl
- >0
- <1.000.000

ist.

Dazu habe ich folgenden Text geschrieben.

//***STARTANZEIGE***
void startanzeige(void)
{
printf("\n\n\n *** WILLKOMMEN BEI U-BOOT-BOMBER ***");
printf("\n\n\n\n\n\n Wie viele Sekunden m\x94 \bchten Sie spielen?\n ");
fflush(stdin); //Tastaturspeicher löschen
do
{ //1=Zahl 0=keine Zahl
scanOK=0;
scanOK=scanf("%f",&zeitvorgabe);

if(zeitvorgabe<0||zeitvorgabe>1000000||!scanOK)
{
printf("\n\n Wie viele Sekunden m\x94 \bchten Sie spielen?\n ");
scanf("%f",&zeitvorgabe);
fflush(stdin); //Tastaturspeicher löschen
}
}
while(zeitvorgabe<0||zeitvorgabe>1000000||!scanOK);

printf("\n\n Anleitung: \n Um Bomben zu werfen dr\x81 \bcken Sie bitte die Taste 'b'!");
printf("\n\n Ziel: \n Alle U-Boote m\x81 \bssen so oft wie m\x94 \bglich getroffen werden!");
printf("\n\n\n INFO:\n Folgende Dienstgrade sind erreichbar: \n Matrose - Gefreiter - Unteroffizier - Offizier - Admiral");


Leider funktioniert es so nur teilweise.
Prinzipiell erkennt das Programm, ob etwas richtiges eingegeben wurde. Nur wenn beim ersten mal z.B. 1000000000000 eingegeben wurde fragt er richtiger weise direkt nocheinmal nach. Wenn hier dann aber etwas eingegeben wird wird die erste Eingabe gar nicht erst erkannt, sondern man muss es nochmal eingeben.

Bestimmt ist es nur ein kleiner Fehler, aber...kann mir jemand von Euch dabei helfen?

Ich muss mein Projekt leider schon am Montag vorstellen. :o(

VG Linda
 
Zuletzt bearbeitet:
Moin Linda,

vorab: bitte halte Dich an die Netiquette und nutze vor allem auch die Code-Tags (#-Button im Editor). Dein geposteter Code ist so quasi nicht lesbar!

Dann: welchen Compiler bzw. Entwicklungsumgebeung nutzt Du denn? So, wie Du es geschreiben, wird es sich nicht compilieren lassen!
Wo und wie sind bspw. die Variablen deklariert ?

Außerdem machst Du es mit Deinem Schleifenkonstrukt viel zu kompliziert!

Hier mal ein anderer (ungetesteter) Ansatz mit anderer Klammerung in der while-Schleife :

C++:
void startanzeige(void)
{
    printf("\n\n\n *** WILLKOMMEN BEI U-BOOT-BOMBER ***");
    bool scanOK = false;
    int zeitvorgabe = 0;

    while( (scanOK == false) && ((zeitvorgabe <= 0) || (zeitvorgabe > 1000000)) )
    {
        printf("\n\n\n\n\n\n Wie viele Sekunden m\x94 \bchten Sie spielen?\n ");
        scanOK = scanf( "%i", &zeitvorgabe );
        fflush(stdin); // Tastaturspeicher löschen
    }

    printf("\n\n Anleitung: \n Um Bomben zu werfen dr\x81 \bcken Sie bitte die Taste 'b'!");
    printf("\n\n Ziel: \n Alle U-Boote m\x81 \bssen so oft wie m\x94 \bglich getroffen werden!");
    printf("\n\n\n INFO:\n Folgende Dienstgrade sind erreichbar: \n Matrose - Gefreiter - Unteroffizier - Offizier - Admiral");
}

Ist scanOK eigentlich wirklich notwendig ?

Gruß
Klaus
 
Zuletzt bearbeitet von einem Moderator:
Klaus, im Prinzip würde ich es so machen wie du. Allerdings glaube ich zu wissen, dass man im Formatstring %d für int-Werte angeben muss (nicht %i). Wenn Ganzzahlen verwendet werden sollen, sollte man aber auf long-Variablen zurückgreifen, im Formatstring als %ld gekennzeichnet. Bei den großen Zahlen von Linda ist die Verwendung von double aber wahrscheinlich sinnvoller.
Die Initialisierung von zeitvorgabe ist nicht notwendig, weil das scanOk alleine schon für den Schleifendurchlauf sorgen sollte. Die Schleifenbedingung ist falsch, die kann Linda so übernehmen wie sie sie schon hatte, aber die Verwendung einer kopfgeprüften Schleife ist ok. Und die Zuweisung eines int-Wertes (der Returncode von scanf) an eine bool-Variable ist auch nicht sauber.
Mein Vorschlag wäre also:

C++:
void startanzeige(void)
{
    printf("\n\n\n *** WILLKOMMEN BEI U-BOOT-BOMBER ***");
    bool scanOK = false;
    long zeitvorgabe;
 
    while( !scanOK || (zeitvorgabe <= 0) || (zeitvorgabe > 1000000) )
    {
        printf("\n\n\n\n\n\n Wie viele Sekunden m\x94 \bchten Sie spielen?\n ");
        scanOK = scanf( "%ld", &zeitvorgabe )==1 ? true : false;
        fflush(stdin); // Tastaturspeicher löschen
    }
 
    printf("\n\n Anleitung: \n Um Bomben zu werfen dr\x81 \bcken Sie bitte die Taste 'b'!");
    printf("\n\n Ziel: \n Alle U-Boote m\x81 \bssen so oft wie m\x94 \bglich getroffen werden!");
    printf("\n\n\n INFO:\n Folgende Dienstgrade sind erreichbar: \n Matrose - Gefreiter - Unteroffizier - Offizier - Admiral");
}

PS: Ich glaube, Linda hatte für zeitvorgabe keine Deklaration im Code.
 
Hallo!

Danke für die schnellen Antworten! Die zweite Antwort hat zu Ziel geführt! :-) :-) :-)
Es tut mir leid wenn ich mich nicht an bestimmte Formen gehalten habe. Das war keine Absicht. Ich bin erst seit ich glaub 2 Stundne hier angemeldet und wusste nicht das es sowas gibt.

Was den Code angeht.. so 100%ig nachvollziehen kann ich ihn nicht, da ich diese Zeile nicht ganz verstehe:
PHP:
scanOK = scanf( "%ld", &zeitvorgabe )==1 ? true : false;
Was sagt das ==1 ? true : false am Ende aus?
Wenn sich die Antwort leicht erklären lässt wäre es super wenn Du das noch machen könntest. Falls nicht ist es auch nicht schlimm weil ich schon mehr als glücklich mit der ersten Antwort bin! :-)

Danke!
 
Wenn das scanf als Returnwert 1 hat, wird scanOK auf true gesetzt, sonst auf false.
Ist nichts anderes als eine Andere Schreibweise für ein if
 
Richtig. Das ?: ist der ternäre Operator, der in C-ähnlichen Sprachen für einfache Fallunterscheidungen verwendet wird, beispielsweise in Makros. Ternär bedeutet das dieser Operator drei Operanden hat. Die Syntax ist
<Bedingung> ? <Ausdruck1> : <Ausdruck>
und bedeutet einfach, dass der Wert von Ausdruck1 zurückgegeben wird, wenn die Bedingung wahr ist, ansonsten der Wert von Ausdruck2. In diesem Fall wird in der Bedingung getestet, ob der Rückgabewert der scanf-Funtion 1 ist. Man hätte natürlich auch schreiben können
C++:
if ( scanf( "%ld", &zeitvorgabe ) == 1 )
{ scanOK = true ; } else
{ scanOK = false; }

Übrigens: füge am besten die Code-Tags von Hand ein, dann verwendest du auch die richtige Sprache. Für C++ ist das ein cpp, das in eckigen Klammern steht.
 
Zuletzt bearbeitet:
Hallo,

noch ein paar Anmerkungen von mir:

C++:
bool scanOK = false;
Linda hat es zwar nicht erwähnt, aber es sieht so aus, als ob sie C lernen würde. Den Datentyp bool gibt es bei C allerdings nicht.

C++:
    while( !scanOK || (zeitvorgabe <= 0) || (zeitvorgabe > 1000000) )
    {
        printf("\n\n\n\n\n\n Wie viele Sekunden m\x94 \bchten Sie spielen?\n ");
        scanOK = scanf( "%ld", &zeitvorgabe )==1 ? true : false;
        fflush(stdin); // Tastaturspeicher löschen
    }
Dieses Konstrukt hat das Potential zur Endlosschleife. Was fflush bei Eingabeströmen bewirkt, ist nämlich nicht definiert bzw. implementationsabhängig. Auf der sicheren Seite ist man, wenn man den Rest der Zeile selbst ausliest:
C:
int c;
while ((c = getchar()) != EOF && c != '\n'); // Leerer Schleifenkörper

Außerdem ist
C++:
scanOK = scanf( "%ld", &zeitvorgabe )==1 ? true : false;
doppelt gemoppelt. Der Ausdruck ist gleichbedeutend mit
C++:
scanOK = scanf( "%ld", &zeitvorgabe )==1;

Grüße,
Matthias
 
Zuletzt bearbeitet von einem Moderator:
Hi.
Allerdings glaube ich zu wissen, dass man im Formatstring %d für int-Werte angeben muss (nicht %i).
Warum schaust du denn nicht nach wenn du dir überhaupt nicht sicher bist bevor du dein "Wissen" hier darbietest? Damit verwirrst du nur die Anfänger (und evtl. andere).

Es gibt beide Format-Spezifiierer. Beide gelten für Integer. Bei %d werden Integer allerdings immer als Dezimalzahlen eingelesen, mit %i kann man auch hexadezimale und oktale Schreibweise verwenden.

Linda hat es zwar nicht erwähnt, aber es sieht so aus, als ob sie C lernen würde. Den Datentyp bool gibt es bei C allerdings nicht.
Auch das stimmt nicht so ganz. Seit C99 gibt es den Typ bool auch in C. Man muss nur stdbool.h einbinden.

Gruß
 
Zurück