Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
iRob
Beiträge: 9
Registriert: Mi Jan 27, 2021 10:50 am

Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von iRob » Sa Mai 28, 2022 5:34 pm

Hallo Freunde,
ich lerne jetzt seit etwa einem Jahr c und bin grad dabei Dinge aufzuarbeiten , die ich bis heute nicht verstanden habe. Über Euren Support würde ich mich freuen. Antworten bitte so einfach und verständlich wie möglich.
Danke und greets, Rob

code-Beispiel:

Code: Alles auswählen

#define us unsigned short
us sorte;
do {
printf("\n\n\n\tWas möchten Sie trinken? ");
    printf("\n\t1. Wasser (0,50 Euro)");
    printf("\n\t2. C.Cola (1,00 Euro)");
    printf("\n\t3. Kölsch (2,00 Euro)");
    printf("\n\n\tGeben Sie 1, 2 oder 3 ein: ");
    scanf("%d", &sorte);
}while (sorte<1||sorte>3); 
Problemstellung:
Wenn versehentlich char (z.B. a) oder float (z.B. 1.1) für 'sorte' eingeben wird, geht das Programm beim nächsten Block in eine Endlosschleife über.

Fragestellung:
Was passiert genau im Hintergrund? Warum passiert das? Und das Wichtigste: Mit welchem code kann ich das Problem sicher abstellen?

Im Grunde bräuchte ich code nach scanf, der char (alles außer ganze Zahlen natürlich) und float nicht zulässt. Gibt es da nicht was Simples?

Edit by Xin: Codetags eingefügt

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von Xin » So Mai 29, 2022 9:12 am

iRob hat geschrieben:
Sa Mai 28, 2022 5:34 pm
Was passiert genau im Hintergrund? Warum passiert das? Und das Wichtigste: Mit welchem code kann ich das Problem sicher abstellen?
scanf mit %d möchte aus der Eingabe ein Integer abholen. 'a' ist kein Integer, also wird 'a' nicht abgeholt und sorte nicht verändert. Sorte ist beim Programmstart (zufällig! aber reproduzierbar) mit 0 initialisiert. Die Bedingung der while-Schleife gibt also true aus und wiederholt sich. 'a' liegt weiter im Eingabepuffer - es wurde ja nicht abgeholt. Es passt aber weiterhin nicht auf %d -> Endlosschleife.

scanf gibt die Zahl der Zeichen zurück, die es verarbeitet hat. Ist die 0, hat die Eingabe nicht auf den Formatstring gepasst. Das kann man ausnutzen.

Code: Alles auswählen

#define us unsigned short
us sorte;
do {
printf("\n\n\n\tWas möchten Sie trinken? ");
    printf("\n\t1. Wasser (0,50 Euro)");
    printf("\n\t2. C.Cola (1,00 Euro)");
    printf("\n\t3. Kölsch (2,00 Euro)");
    printf("\n\n\tGeben Sie 1, 2 oder 3 ein: ");
    int l = scanf("%d", &sorte);
    
    if( l == 0 )
    {
        printf("Fehlerhafte Eingabe\n");
        break;
    }
}while (sorte<1||sorte>3); 
Um die Wiederholung zu machen, muss erst die Falsche Eingabe aus dem Input-Puffer raus.
Schau mal hier:
Löschen des Input-Puffers
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

iRob
Beiträge: 9
Registriert: Mi Jan 27, 2021 10:50 am

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von iRob » So Mai 29, 2022 3:32 pm

supi, danke für die Antwort

iRob
Beiträge: 9
Registriert: Mi Jan 27, 2021 10:50 am

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von iRob » Do Jun 09, 2022 5:52 pm

Ich hab noch eine Frage, weiß aber nicht, ob ich das gleich hier machen kann. Ich versuchs mal:

Folgendes Programm soll bei der Eingabe von Enter beenden. Macht es auch, aber erst wenn ich das 2. Mal Enter drücke.
Warum ist das so und wie muss der Code aussehen, damit das Programm beim 1. Enter endet?

#include <stdio.h>
#include <stdlib.h>

int main () {
int ch;

printf ("\n\n Weiter mit Enter");
while((ch = getchar()) != '\n' && ch != EOF);
if (ch=getchar () == "\n")
return 0;
}

iRob
Beiträge: 9
Registriert: Mi Jan 27, 2021 10:50 am

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von iRob » Do Jun 09, 2022 6:50 pm

Man, bin ich blöd. Die Frage hat sich erledigt. Danke trotzdem.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von Xin » Do Jun 09, 2022 9:56 pm

Dann lassen wir das unkommentiert stehen. :D
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

iRob
Beiträge: 9
Registriert: Mi Jan 27, 2021 10:50 am

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von iRob » Di Jun 21, 2022 11:48 am

Ich bin's noch mal, hi. Hab eine weiteren Frage zum Puffer und dessen Arbeitsweise. Hoffe, du kannst helfen.

Als Lern-Projekte möchte ich eine Steuerung für mein Gewächshaus programmieren (weiter unten ist mein bisheriges Listing), welches dann mit den nötigen Sensoren auf einem Raspberry Pico laufen soll.

Soll-Funktion:
In der manuellen Heizungs- und Luftsteuerung können sechs verschiedene An- und Auszeiten sowie max. und min. Temperatur eingeben werden . Nach der 6. Eingabe soll automatisch der Text "Ihre Einstellungen wurden gespeichert. Weiter mit Enter" erscheinen.

Ist-Funktion:
Ich muss bei "Heizung", " Manuelle Einstellung", zusätzlich nach dem Enter für die Eingabe der letzten Zahl der 6. Eingabe noch ein Enter eingeben, damit "Ihre Einstellungen wurden gespeichert" erscheint . Und dann noch ein Enter, damit "Weiter mit Enter" erscheint. Bei "Luft", "Manuelle Einstellung", muss ich gleich 2 x Enter nach der Eingabe der letzten Zahl beim 3. Ventilator eingeben.
Bei "Licht", "Manuelle Einstellung", funktioniert es einwandfrei. Da kann man gut sehen, wie es sein soll.
Zum testen:
Start des Codes. Im Menue die 1 für "Heizung" oder 3 für "Luft" eingeben, dann die 3 für "Manuelle Eingabe" und bei allen 6 Schaltungen beispielsweise Start-Zeit 2, Stopp-Zeit 3, Mindest-Temperatur 22, Maximal-Temperatur 23 eingeben bzw. bei allen 3 Schaltungen "Start-Zeit" 2 und "Stopp-Zeit" 3, dann tritt der Fehler auf.
Betroffen sind die Funktionen "void _heizung ()" und "void _luft". In den Zeilen 100 und 200 etwa habe ich den möglichen Fehlerbereich mit "FEHLER" markiert .

Ich denke, es hat wieder mit dem Puffer zu tun. Leider finde ich im Netz wenig spezifische Lektüre zu dem Thema. Ich würde gerne detailliert verstehen, was da passiert, damit ich irgendwann stabile Programme schreiben kann. Ein Lösungsvorschlag wäre auch toll. Zudem gerne Tipps und praktische Beispiele, wie ich den Puffer komplett verstehen kann.
while ((ch = getchar()) != '\n' && ch != EOF) (tue nichts); hab ich durch deinen letzten Tipp zum Löschen von Puffer gefunden. Damit wird alles im Puffer gelöscht, außer \n. Warum löscht man das nicht gleich mit? Wenn es stehen bleibt, stehen doch bei der nächsten Eingabe schon zwei \n im Puffer, oder? Und wie verhält es sich bei fgets (), wenn am Ende \n und \0 steht?

Danke für deine Mühe!

Edited by Xin: Codetags hinzugefügt

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#define us unsigned short

void _heizung ();
us _eingabePruefungH (us *startzeitHeiz, us *stoppzeitHeiz, us *temperaturMin, us *temperaturMax);
void _licht ();
us _eingabePruefungLi (us *startzeitLicht, us *stoppzeitLicht);
void _luft ();
us _eingabePruefungLu (us *startzeitLuft, us *stoppzeitLuft);
us _menue ();
void _weiter ();


int main () {
    us auswahl = 0;
    char ch;

    while (1) {
        do {
            printf("\n\n   HAUPTMENÜ\n");
            printf ("\n   1. Heizung");
            printf ("\n   2. Licht");
            printf ("\n   3. Luft");
            printf ("\n   4. Ende");
            printf("\n\n   Geben Sie 1 - 4 ein und drücken Enter ");

            if (ch=scanf("%d", &auswahl)==0)
                getchar ();
        } while (auswahl < 1 || auswahl > 4);

        switch (auswahl) {
        case 1:
            _heizung ();
            break;
        case 2:
            _licht ();
            break;
        case 3:
            _luft ();
            break;
        case 4:
            printf("\n\n   Bis bald!");
            exit (0);
        default:
            break;
        }
    }
    return EXIT_FAILURE;
}

void _heizung () {
    us ch, i = 0, menue = 0;
    char jn;
    us startzeitHeiz[6] = {0};
    us stoppzeitHeiz[6] = {0};
    us temperaturMin[6] = {0};
    us temperaturMax[6] = {0};

    printf ("\n\n   HEIZUNG ");
    menue = _menue ();

    switch (menue) {
    case 1:
        printf("\n\n   Die Automatik wurde aktiviert:");
        printf("\n   Die Tagestemperatur beträgt xy");
        printf("\n   Die Nachttemperatur beträgt xy");
        //aktiviere die Automatik
        _weiter ();
        return;
    case 2:
        printf("\n\n   Die Automatik wurde aktiviert:");
        printf("\n   Die Tagestemperatur beträgt xy");
        printf("\n   Die Nachttemperatur beträgt xy");
        //aktiviere die Automatik
        _weiter ();
        return;
    case 3:
        printf("\n\n   MANUELLE EINSTELLUNG");
        printf("\n\n   Geben Sie die Start- und Stoppzeit(en) und"
               "\n   den dazu gewünschten Temperaturbereich ein:");
        do {
            do {
                printf("\n\n   %d. Start-Zeit: ", i+1);
                scanf("%d", &startzeitHeiz[i]);
                printf("   %d. Stopp-Zeit: ", i+1);
                scanf("%d", &stoppzeitHeiz[i]);
                printf("   %d. Mindest-Temperatur: ", i+1);
                scanf("%d", &temperaturMin[i]);
                printf("   %d. Hoechst-Temperatur: ", i+1);
                scanf("%d", &temperaturMax[i]);
                ch = _eingabePruefungH (&startzeitHeiz[i], &stoppzeitHeiz[i], &temperaturMin[i], &temperaturMax[i]);
            } while (ch == 1);
            if (i < 5) {
                printf("\n\n   Sie können noch weitere Start-/Stoppzeiten eingeben.");
                printf ("\n\n   Weitere Eingaben mit (j), ansonsten (n): ");
                i++;
            }
            while ((ch = getchar()) != '\n' && ch != EOF);
                jn = getchar ();       //scanf("%c", &jn);
        } while (jn == 'j' && i < 6);
        //aktiviere die manuelle Steuerung 
        //FEHLER: Ende i=6 muss zwei Mal Enter gedrückt werden
        printf("\n   Ihre Einstellungen wurden gespeichert\n");
        i = 0;
        while ((ch = getchar()) != '\n' && ch != EOF);
        _weiter ();
        //FEHLER: Hier muss noch mal Enter gedrückt werden
        return;
    default:
        exit (0);
    }
}

void _licht () {
    us ch, menue = 0;
    us startzeitLicht[1] = {0};
    us stoppzeitLicht[1] = {0};

    printf ("\n\n   LICHT ");
    menue = _menue ();

    switch (menue) {
    case 1:
        printf("\n\n   Die Automatik wurde aktiviert:");
        printf("\n   Die Beleuchtung erfolgt von xy");
        //aktiviere die Automatik
        _weiter ();
        return;
    case 2:
        printf("\n\n   Die Automatik wurde aktiviert:");
        printf("\n   Die Beleuchtung erfolgt von xy");
        //aktiviere die Automatik
        _weiter ();
        return;
    case 3:
        do {
            printf("\n\n   MANUELLE EINSTELLUNG");
            printf("\n\n   Geben Sie die Start- und Stoppzeit (0 - 24) ein:");
            printf("\n\n   Start-Zeit: ");
            scanf("%d", &startzeitLicht);
            printf("   Stopp-Zeit: ");
            scanf("%d", &stoppzeitLicht);
            ch = _eingabePruefungLi (&startzeitLicht, &stoppzeitLicht);
        } while (ch == 1);
        //aktiviere die manuelle Steuerung 
        while( (ch = getchar()) != '\n' && ch != EOF );
        printf("\n   Ihre Einstellungen wurden gespeichert\n");
        _weiter ();
        return;
    default:
        exit (0);
    }
    return;
}

void _luft () {
    us ch, i = 0, menue = 0; 
    char jn;
    us startzeitLuft[3] = {0};
    us stoppzeitLuft[3] = {0};

    printf ("\n\n   LUFT ");
    menue = _menue ();

    switch (menue) {
    case 1:
        printf("\n\n   Die Automatik wurde aktiviert:");
        printf("\n   Der Ventilator läuft von xy");
        //aktiviere die Automatik
        _weiter ();
        return;
    case 2:
        printf("\n\n   Die Automatik wurde aktiviert:");
        printf("\n   Der Ventilator läuft durchgehend");
        //aktiviere die Automatik
        _weiter ();
        return;
    case 3:
        printf("\n\n   MANUELLE EINSTELLUNG");
        printf("\n\n   Geben Sie die Start- und Stoppzeit(en 0 - 24) ein:");
        do {
            do {
                printf("\n\n   %d. Ventilator", i+1);
                printf("\n      Start-Zeit (Steckdose %d): ", i+1);
                scanf("%d", &startzeitLuft[i]);
                printf("      Stopp-Zeit (Steckdose %d): ", i+1);
                scanf("%d", &stoppzeitLuft[i]);
                ch = _eingabePruefungLu (&startzeitLuft[i], &stoppzeitLuft[i]);
            } while (ch == 1);
            if (i < 2) {
                printf ("\n\n   Weiteren Lüfter zuschalten mit (j), ansonsten (n): ");
            }
            while ((ch = getchar()) != '\n' && ch != EOF);
            jn = getchar ();       //scanf("%c", &jn);
            i++;
        } while (jn == 'j' && i < 3);
        //aktiviere die manuelle Steuerung 
        //FEHLER: Ende i=3 muss zwei Mal Enter gedrückt werden
        while ((ch = getchar()) != '\n' && ch != EOF);
        printf("\n   Ihre Einstellungen wurden gespeichert\n");
        i = 0;
        _weiter ();
        return;
    }
}

us _menue () {
    us menue, ch;

    do {
        printf ("\n\n   1. Automatik aktivieren "
                "\n   2. Automatik aktivieren "
                "\n   3. Manuelle Einstellung");
        printf ("\n\n   Geben Sie 1, 2 oder 3 ein und drücken Enter ");
        while( (ch = getchar()) != '\n' && ch != EOF );
        if ((ch=scanf("%d", &menue)) == 0);
        getchar ();
    } while (menue < 1 || menue > 3 || ch == 0);

    return menue;
}

void _weiter () {

    printf ("\n\n   Weiter mit Enter");
    if (getchar () == "\n")
        return;
}

us _eingabePruefungH (us *startzeitHeiz, us *stoppzeitHeiz, us *temperaturMin, us *temperaturMax) {

    if (*startzeitHeiz >= 0 && *startzeitHeiz <= 24) {
        if (*stoppzeitHeiz >= 0 && *stoppzeitHeiz <= 24) {
            if (*startzeitHeiz != *stoppzeitHeiz) {
                if (*temperaturMin >= 18 && *temperaturMin <= 28) {
                    if (*temperaturMax >= 20 && *temperaturMax <=30) {
                        if (*temperaturMin < *temperaturMax) {
                            return 0;
                        }
                    }
                }
            }
        }
    }
    printf("\n   Uuups, da war was falsch, bitte erneut eingeben.\n");
    return 1;
}

us _eingabePruefungLi (us *startzeitLicht, us *stoppzeitLicht) {

    if (*startzeitLicht >= 0 && *startzeitLicht <= 24) {
        if (*stoppzeitLicht >= 0 && *stoppzeitLicht <= 24) {
            if (*startzeitLicht != stoppzeitLicht) {
                return 0;
            }
        }
    }
    printf("\n   Uuups, da war was falsch, bitte erneut eingeben.\n");
    return 1;
}


us _eingabePruefungLu (us *startzeitLuft, us *stoppzeitLuft) {

    if (*startzeitLuft >= 0 && *startzeitLuft <= 24) {
        if (*stoppzeitLuft >= 0 && *stoppzeitLuft <= 24) {
            if (*startzeitLuft != *stoppzeitLuft) {
                return 0;
            }
        }
    }
    printf("\n   Uuups, da war was falsch, bitte erneut eingeben.\n");
    return 1;
}

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von Xin » Mi Jun 22, 2022 4:33 pm

Ich habe Fragen...

Das ist erstmal, was der Compiler rauswirft:

Code: Alles auswählen

xin@Ryzen:~/prg.org/iRob$ gcc gewaechshaus.c 
gewaechshaus.c: In function ‘main’:
gewaechshaus.c:28:28: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
   28 |             if (ch=scanf("%d", &auswahl)==0)
      |                           ~^   ~~~~~~~~
      |                            |   |
      |                            |   short unsigned int *
      |                            int *
      |                           %hd
gewaechshaus.c: In function ‘_heizung’:
gewaechshaus.c:85:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
   85 |                 scanf("%d", &startzeitHeiz[i]);
      |                        ~^   ~~~~~~~~~~~~~~~~~
      |                         |   |
      |                         |   short unsigned int *
      |                         int *
      |                        %hd
gewaechshaus.c:87:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
   87 |                 scanf("%d", &stoppzeitHeiz[i]);
      |                        ~^   ~~~~~~~~~~~~~~~~~
      |                         |   |
      |                         |   short unsigned int *
      |                         int *
      |                        %hd
gewaechshaus.c:89:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
   89 |                 scanf("%d", &temperaturMin[i]);
      |                        ~^   ~~~~~~~~~~~~~~~~~
      |                         |   |
      |                         |   short unsigned int *
      |                         int *
      |                        %hd
gewaechshaus.c:91:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
   91 |                 scanf("%d", &temperaturMax[i]);
      |                        ~^   ~~~~~~~~~~~~~~~~~
      |                         |   |
      |                         |   short unsigned int *
      |                         int *
      |                        %hd
gewaechshaus.c: In function ‘_licht’:
gewaechshaus.c:141:21: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int (*)[1]’ [-Wformat=]
  141 |             scanf("%d", &startzeitLicht);
      |                    ~^   ~~~~~~~~~~~~~~~
      |                     |   |
      |                     |   short unsigned int (*)[1]
      |                     int *
gewaechshaus.c:143:21: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int (*)[1]’ [-Wformat=]
  143 |             scanf("%d", &stoppzeitLicht);
      |                    ~^   ~~~~~~~~~~~~~~~
      |                     |   |
      |                     |   short unsigned int (*)[1]
      |                     int *
gewaechshaus.c:144:38: warning: passing argument 1 of ‘_eingabePruefungLi’ from incompatible pointer type [-Wincompatible-pointer-types]
  144 |             ch = _eingabePruefungLi (&startzeitLicht, &stoppzeitLicht);
      |                                      ^~~~~~~~~~~~~~~
      |                                      |
      |                                      short unsigned int (*)[1]
gewaechshaus.c:8:28: note: expected ‘short unsigned int *’ but argument is of type ‘short unsigned int (*)[1]’
    8 | us _eingabePruefungLi (us *startzeitLicht, us *stoppzeitLicht);
      |                            ^
gewaechshaus.c:144:55: warning: passing argument 2 of ‘_eingabePruefungLi’ from incompatible pointer type [-Wincompatible-pointer-types]
  144 |             ch = _eingabePruefungLi (&startzeitLicht, &stoppzeitLicht);
      |                                                       ^~~~~~~~~~~~~~~
      |                                                       |
      |                                                       short unsigned int (*)[1]
gewaechshaus.c:8:48: note: expected ‘short unsigned int *’ but argument is of type ‘short unsigned int (*)[1]’
    8 | us _eingabePruefungLi (us *startzeitLicht, us *stoppzeitLicht);
      |                                                ^
gewaechshaus.c: In function ‘_luft’:
gewaechshaus.c:186:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
  186 |                 scanf("%d", &startzeitLuft[i]);
      |                        ~^   ~~~~~~~~~~~~~~~~~
      |                         |   |
      |                         |   short unsigned int *
      |                         int *
      |                        %hd
gewaechshaus.c:188:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
  188 |                 scanf("%d", &stoppzeitLuft[i]);
      |                        ~^   ~~~~~~~~~~~~~~~~~
      |                         |   |
      |                         |   short unsigned int *
      |                         int *
      |                        %hd
gewaechshaus.c: In function ‘_menue’:
gewaechshaus.c:217:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat=]
  217 |         if ((ch=scanf("%d", &menue)) == 0);
      |                        ~^   ~~~~~~
      |                         |   |
      |                         |   short unsigned int *
      |                         int *
      |                        %hd
gewaechshaus.c: In function ‘_weiter’:
gewaechshaus.c:227:20: warning: comparison between pointer and integer
  227 |     if (getchar () == "\n")
      |                    ^~
gewaechshaus.c: In function ‘_eingabePruefungLi’:
gewaechshaus.c:254:33: warning: comparison between pointer and integer
  254 |             if (*startzeitLicht != stoppzeitLicht) {
      |                                 ^~
Das sollte der Compiler nicht rauswerfen. ^^
Und ich bin eher überrascht, dass er das als Warning rauspfeffert, aber ich kompiliere auch normalerweise C++. C++ ist da strenger, der Compiler verweigert den Code zu kompilieren mit 3 Fehlern.

Kompiliert wurde mit gcc 10.3.
bei allen 3 Schaltungen "Start-Zeit" 2 und "Stopp-Zeit" 3, dann tritt der Fehler auf. [...] Ich denke, es hat wieder mit dem Puffer zu tun.
Nein, das Programm tut genau das, was es tun soll.
Du willst vermutlich nur was anderes. :-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

iRob
Beiträge: 9
Registriert: Mi Jan 27, 2021 10:50 am

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von iRob » Fr Jul 08, 2022 11:13 am

War einige Tage mit der Umstellung von "Coding C", also einem Linux-Compiler auf meinem Tablet, auf die IDE Code::Blocks (mit GCC für C) unter MS Windows auf meinem Laptop beschäftigt. Da hatte ich auch wieder einige (Start)Probleme und ähnliche Fehlermeldungen wie du.
Zuerst einmal haben ich das define us gelöscht und überall durch int ersetzt. Dazu noch an anderer Stelle paar Klammern gesetzt und siehe da, das Programm läuft wieder. Allerdings ist mein oben beschriebenes Problem geblieben und ich habe immer nock keine Lösungs-Idee.
Folgend der modifizierte Code. Hoffe, er läuft diesmal bei dir.

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
void _heizung ();
int _eingabePruefungH (int *startzeitHeiz, int *stoppzeitHeiz, int *temperaturMin, int *temperaturMax);
void _licht ();
int _eingabePruefungLi (int *startzeitLicht, int *stoppzeitLicht);
void _luft ();
int _eingabePruefungLu (int *startzeitLuft, int *stoppzeitLuft);
int _menue ();
void _weiter ();

int main ()
{
    int auswahl = 0, ch;
    while (1)
    {
        do
        {
            printf("\n\n HAUPTMENUE\n");
            printf ("\n 1. Heizung");
            printf ("\n 2. Licht");
            printf ("\n 3. Luft");
            printf ("\n 4. Ende");
            printf("\n\n Geben Sie 1 - 4 ein und druecken Enter ");
            if (ch=scanf("%d", &auswahl)==0)
                getchar ();
        }
        while (auswahl < 1 || auswahl > 4);
        switch (auswahl)
        {
        case 1:
            _heizung ();
            break;
        case 2:
            _licht ();
            break;
        case 3:
            _luft ();
            break;
        case 4:
            printf("\n\n Bis bald!");
            exit (0);
        default:
            break;
        }
    }
    return EXIT_FAILURE;
}
void _heizung ()
{
    int ch, i = 0, menue = 0;
    char jn;
    int startzeitHeiz[6] = {0};
    int stoppzeitHeiz[6] = {0};
    int temperaturMin[6] = {0};
    int temperaturMax[6] = {0};
    printf ("\n\n HEIZUNG ");
    menue = _menue ();
    switch (menue)
    {
    case 1:
        printf("\n\n Die Automatik wurde aktiviert:");
        printf("\n Die Tagestemperatur beträgt xy");
        printf("\n Die Nachttemperatur beträgt xy");
//aktiviere die Automatik
        _weiter ();
        return;
    case 2:
        printf("\n\n Die Automatik wurde aktiviert:");
        printf("\n Die Tagestemperatur beträgt xy");
        printf("\n Die Nachttemperatur beträgt xy");
//aktiviere die Automatik
        _weiter ();
        return;
    case 3:
        printf("\n\n MANUELLE EINSTELLUNG");
        printf("\n\n Geben Sie die Start- und Stoppzeit(en) und"
               "\n den dazu gewuenschten Temperaturbereich ein:");
        do
        {
            do
            {
                printf("\n\n %d. Start-Zeit: ", i+1);
                scanf("%d", &startzeitHeiz[i]);
                printf(" %d. Stopp-Zeit: ", i+1);
                scanf("%d", &stoppzeitHeiz[i]);
                printf(" %d. Mindest-Temperatur: ", i+1);
                scanf("%d", &temperaturMin[i]);
                printf(" %d. Hoechst-Temperatur: ", i+1);
                scanf("%d", &temperaturMax[i]);
                ch = _eingabePruefungH (&startzeitHeiz[i], &stoppzeitHeiz[i], &temperaturMin[i], &temperaturMax[i]);
            }
            while (ch == 1);
            if (i < 5)
            {
                printf("\n\n Sie koennen noch weitere Start-/Stoppzeiten eingeben.");
                printf ("\n\n Weitere Eingaben mit (j), ansonsten (n): ");
                i++;
            }
            while ((ch = getchar()) != '\n' && ch != EOF);
            jn = getchar (); //scanf("%c", &jn);
        }
        while (jn == 'j' && i < 6);
//aktiviere die manuelle Steuerung
//FEHLER: Ende i=6 muss zwei Mal Enter gedrückt werden
        printf("\n Ihre Einstellungen wurden gespeichert\n");
        i = 0;
        while ((ch = getchar()) != '\n' && ch != EOF);
        _weiter ();
//FEHLER: Hier muss noch mal Enter gedrückt werden
        return;
    default:
        exit (0);
    }}
        void _licht ()
        {
            int ch, menue = 0;
            int startzeitLicht[1] = {0};
            int stoppzeitLicht[1] = {0};
            printf ("\n\n LICHT ");
            menue = _menue ();
            switch (menue)
            {
            case 1:
                printf("\n\n Die Automatik wurde aktiviert:");
                printf("\n Die Beleuchtung erfolgt von xy");
//aktiviere die Automatik
                _weiter ();
                return;
            case 2:
                printf("\n\n Die Automatik wurde aktiviert:");
                printf("\n Die Beleuchtung erfolgt von xy");
//aktiviere die Automatik
                _weiter ();
                return;
            case 3:
                do
                {
                    printf("\n\n MANUELLE EINSTELLUNG");
                    printf("\n\n Geben Sie die Start- und Stoppzeit (0 - 24) ein:");
                    printf("\n\n Start-Zeit: ");
                    scanf("%d", &startzeitLicht);
                    printf(" Stopp-Zeit: ");
                    scanf("%d", &stoppzeitLicht);
                    ch = (_eingabePruefungLi (startzeitLicht, stoppzeitLicht));
                }
                while (ch == 1);
//aktiviere die manuelle Steuerung
                while( (ch = getchar()) != '\n' && ch != EOF );
                printf("\n Ihre Einstellungen wurden gespeichert\n");
                _weiter ();
                return;
            default:
                exit (0);
            }
            return;
        }
        void _luft ()
        {
            int ch, i = 0, menue = 0;
            char jn;
            int startzeitLuft[3] = {0};
            int stoppzeitLuft[3] = {0};
            printf ("\n\n LUFT ");
            menue = _menue ();
            switch (menue)
            {
            case 1:
                printf("\n\n Die Automatik wurde aktiviert:");
                printf("\n Der Ventilator laeuft von xy");
//aktiviere die Automatik
                _weiter ();
                return;
            case 2:
                printf("\n\n Die Automatik wurde aktiviert:");
                printf("\n Der Ventilator laeuft durchgehend");
//aktiviere die Automatik
                _weiter ();
                return;
            case 3:
                printf("\n\n MANUELLE EINSTELLUNG");
                printf("\n\n Geben Sie die Start- und Stoppzeit(en 0 - 24) ein:");
                do
                {
                    do
                    {
                        printf("\n\n %d. Ventilator", i+1);
                        printf("\n Start-Zeit (Steckdose %d): ", i+1);
                        scanf("%d", &startzeitLuft[i]);
                        printf(" Stopp-Zeit (Steckdose %d): ", i+1);
                        scanf("%d", &stoppzeitLuft[i]);
                        ch = _eingabePruefungLu (&startzeitLuft[i], &stoppzeitLuft[i]);
                    }
                    while (ch == 1);
                    if (i < 2)
                    {
                        printf ("\n\n Weiteren Luefter zuschalten mit (j), ansonsten (n): ");
                    }
                    while ((ch = getchar()) != '\n' && ch != EOF);
                    jn = getchar (); //scanf("%c", &jn);
                    i++;
                }
                while (jn == 'j' && i < 3);
//aktiviere die manuelle Steuerung
//FEHLER: Ende i=3 muss zwei Mal Enter gedrückt werden
                while ((ch = getchar()) != '\n' && ch != EOF);
                i = 0;
                printf("\n Ihre Einstellungen wurden gespeichert\n");
                _weiter ();
                return;
            }
        }
        int _menue ()
        {
            int menue, ch;
            do
            {
                printf ("\n\n 1. Automatik aktivieren "
                        "\n 2. Automatik aktivieren "
                        "\n 3. Manuelle Einstellung");
                printf ("\n\n Geben Sie 1, 2 oder 3 ein und druecken Enter ");
                while( (ch = getchar()) != '\n' && ch != EOF );
                if ((ch=scanf("%d", &menue)) == 0);
                getchar ();
            }
            while (menue < 1 || menue > 3 || ch == 0);
            return menue;
        }
        void _weiter ()
        {
            printf ("\n\n Weiter mit Enter");
            if (getchar () == '\n')
            {
                return;
            }
        }
        int _eingabePruefungH (int *startzeitHeiz, int *stoppzeitHeiz, int *temperaturMin, int *temperaturMax)
        {
            if (*startzeitHeiz >= 0 && *startzeitHeiz <= 24)
            {
                if (*stoppzeitHeiz >= 0 && *stoppzeitHeiz <= 24)
                {
                    if (*startzeitHeiz != *stoppzeitHeiz)
                    {
                        if (*temperaturMin >= 18 && *temperaturMin <= 28)
                        {
                            if (*temperaturMax >= 20 && *temperaturMax <=30)
                            {
                                if (*temperaturMin < *temperaturMax)
                                {
                                    return 0;
                                }
                            }
                        }
                    }
                }
            }
            printf("\n Uuups, da war was falsch, bitte erneut eingeben.\a\n");
            return 1;
        }
        int _eingabePruefungLi (int *startzeitLicht, int *stoppzeitLicht)
        {
            if (*startzeitLicht >= 0 && *startzeitLicht <= 24)
            {
                if (*stoppzeitLicht >= 0 && *stoppzeitLicht <= 24)
                {
                    if (*startzeitLicht != *stoppzeitLicht)
                    {
                        return 0;
                    }
                }
            }
            printf("\n Uuups, da war was falsch, bitte erneut eingeben.\a\n");
            return 1;
        }

        int _eingabePruefungLu (int *startzeitLuft, int *stoppzeitLuft)
        {
            if (*startzeitLuft >= 0 && *startzeitLuft <= 24)
            {
                if (*stoppzeitLuft >= 0 && *stoppzeitLuft <= 24)
                {
                    if (*startzeitLuft != *stoppzeitLuft)
                    {
                        return 0;
                    }
                }
            }
            printf("\n Uuups, da war was falsch, bitte erneut eingeben.\a\n");
            return 1;
        }
Edited by Xin: Codetags hinzugefügt.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Wie char und float bei scanf für Weiterverarbeitung eliminieren?

Beitrag von Xin » Mo Jul 11, 2022 9:08 pm

Soo.... sorry, ich hatte das Posting gesehen, aber dann im sonstigen Trubel aus den Augen verloren.
iRob hat geschrieben:
Fr Jul 08, 2022 11:13 am
siehe da, das Programm läuft wieder. Allerdings ist mein oben beschriebenes Problem geblieben und ich habe immer nock keine Lösungs-Idee.
Folgend der modifizierte Code. Hoffe, er läuft diesmal bei dir.
Wie bist Du auf die Idee gekommen, alle Funktionen mit einem Unterstrich beginnen zu lassen.
Das ist keine gute Idee, das ist eher internen Funktionen vorbehalten.

Der folgende Code... ich habe jetzt nicht nochmal geguckt, ob sich da was geändert hat, aber bitte erkläre mir doch mal
den folgenden Code, ab der Markierung.

Code: Alles auswählen

        do
        {
            do
            {
                printf("\n\n %d. Start-Zeit: ", i+1);
                scanf("%d", &startzeitHeiz[i]);
                printf(" %d. Stopp-Zeit: ", i+1);
                scanf("%d", &stoppzeitHeiz[i]);
                printf(" %d. Mindest-Temperatur: ", i+1);
                scanf("%d", &temperaturMin[i]);
                printf(" %d. Hoechst-Temperatur: ", i+1);
                scanf("%d", &temperaturMax[i]);
                ch = _eingabePruefungH (&startzeitHeiz[i], &stoppzeitHeiz[i], &temperaturMin[i], &temperaturMax[i]);
            }
            while (ch == 1);

// AB HIER ERKLÄREN            
            
            if (i < 5)                                                                                       
            {
                printf("\n\n Sie koennen noch weitere Start-/Stoppzeiten eingeben.");
                printf ("\n\n Weitere Eingaben mit (j), ansonsten (n): ");
                i++;
            }
            while ((ch = getchar()) != '\n' && ch != EOF);                            
            jn = getchar (); //scanf("%c", &jn);
        }
        while (jn == 'j' && i < 6);
//aktiviere die manuelle Steuerung
//FEHLER: Ende i=6 muss zwei Mal Enter gedrückt werden
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten