Forum: PC-Programmierung Scanf liest Zahl falsch ein


von Daniel S. (dani2304)


Lesenswert?

Hallo,
ich habe nochmal ein Problem. Beim Einlesen von den Zahlen beim Monat 
&MM die Zahl '08' als '0' in &MM und '8' in &JJJJ abgespeichert. Weiß 
einer warum?
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
void clean_stdin(void)                              // Löschen des Tastaturpuffers
5
{
6
    int c;
7
    do {
8
        c = getchar();
9
    } while (c != '\n' && c != EOF);                        // Beenden des Loops sobald EOF erreicht ist
10
}
11
int main()
12
{
13
    int TT, MM, JJJJ, i, Tage=0;                          // Deklarieren der Variablen
14
    int Monat[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};              // Deklarieren eines Arrays mit den Anfangswerten
15
    printf("Geben Sie das Datum ein: TT, MM, JJJJ\n");                // Aufforderung zur Eingabe des Datums
16
    scanf("%i",&TT);                                // Speichern der Eingabe
17
    scanf("%i",&MM);
18
    scanf("%i",&JJJJ);
19
    clean_stdin();
20
    printf("%i %i %i",TT,MM,JJJJ);
21
    if(!(JJJJ%4)) Monat[2]=29;                            // Schaltjahr: Erhöhen der Tage im Februar
22
23
    while(MM<0 || MM>12 || TT<1 || TT>Monat[MM]){                  // Fehlerfall: falsche Datumseingabe
24
      clean_stdin();                                // Löschen Tastaturpuffer
25
        printf("Unbekanntes Datum! Bitte erneut eingeben! TT, MM, JJJJ\n");      // Aufforderung erneute Eingabe
26
        scanf("%i %i %i",&TT,&MM,&JJJJ);                      // Speichern der neuen Werte
27
        if(!(JJJJ%4)) Monat[2]=29;                          // Schaltjahr: Ein Tag mehr
28
        else Monat[2]=28;                              // Normalfall
29
    }
30
                                            // Berechnung der Tage:
31
    for(i=1; i<MM;i++){
32
        Tage+=Monat[i];
33
    }
34
    Tage+=TT;
35
    printf("Das Datum ist der %i. Tag im Jahr %i", Tage, JJJJ);            // Ausgabe der verbleibenden Tage im Jahr
36
    return 0;
37
}

Die Abstände der Kommentare sind leider verschoben :/

von g457 (Gast)


Lesenswert?

> Beim Einlesen von den Zahlen beim Monat &MM die Zahl '08' als '0' in &MM
> und '8' in &JJJJ abgespeichert.

Analog auch beim Tag und beim Jahr.

> Weiß einer warum?

'08' -> Oktalzahl -> '8' ist keine gültige Oktalziffer -> scanf bricht 
ab.

von Daniel S. (dani2304)


Lesenswert?

Und was mach ich dann?

von Dirk B. (dirkb2)


Lesenswert?

Du nimmst den richtigen Formatspecifier für Dezimalzahlen.

Zum Einlesen von int gibt es mehrere bei scanf.
Z.B kannst du mit %o oktale und mit %x hexadezimale Interpretation 
erzwingen.

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

Daniel S. schrieb:
> if(!(JJJJ%4)) Monat[2]=29;
Ein Schaltjahr ist es, wenn:
- das Jahr (restlos) durch 4 geteilt werden kann, oder
- das Jahr (restlos) durch 4 und 400 teilbar ist.
1700, 1800 und 1900 sind zwar durch 4 teilbar, sind aber trotzdem keine 
Schaltjahre gewesen. Das Jahr 2000 hingegen war ein Schaltjahr.

Nennt sich Säkularjahr.
https://de.wikipedia.org/wiki/S%C3%A4kularjahr


Daniel S. schrieb:
> printf("Geben Sie das Datum ein: TT, MM, JJJJ\n");                //
> Aufforderung zur Eingabe des Datums
>     scanf("%i",&TT);                                // Speichern der
> Eingabe
>     scanf("%i",&MM);
>     scanf("%i",&JJJJ);
>     clean_stdin();
>     printf("%i %i %i",TT,MM,JJJJ);
>     if(!(JJJJ%4)) Monat[2]=29;                            // Schaltjahr:
> Erhöhen der Tage im Februar
>
>     while(MM<0 || MM>12 || TT<1 || TT>Monat[MM]){                  //
> Fehlerfall: falsche Datumseingabe
>       clean_stdin();                                // Löschen
> Tastaturpuffer
>         printf("Unbekanntes Datum! Bitte erneut eingeben! TT, MM,
> JJJJ\n");      // Aufforderung erneute Eingabe
>         scanf("%i %i %i",&TT,&MM,&JJJJ);                      //
> Speichern der neuen Werte
>         if(!(JJJJ%4)) Monat[2]=29;                          //
> Schaltjahr: Ein Tag mehr
>         else Monat[2]=28;                              // Normalfall
>     }
Das kannst du dir einfacher machen, in dem du eine do-while-Schleife 
benutzt.

von MaWin (Gast)


Lesenswert?

Dirk B. schrieb:
> Du nimmst den richtigen Formatspecifier für Dezimalzahlen.

Und der wäre?

von Ralf D. (doeblitz)


Lesenswert?

MaWin schrieb:
> Dirk B. schrieb:
>> Du nimmst den richtigen Formatspecifier für Dezimalzahlen.
>
> Und der wäre?

%d, lies doch einfach mal die manpage der Funktion, in der steht auch 
genau drin, wieso du mit %i und "08" Probleme bekommst.

von Dirk B. (dirkb2)


Lesenswert?

Da hätte man vielleicht auch selber drauf kommen können.

Aber Annahmen sind beim Programmieren ungünstig.
Man muss wissen was man schreibt.

Daher ist der Hinweis auf die Manpages oder Online-Referenzen 
hilfreicher als das %d.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.