Forum: Mikrocontroller und Digitale Elektronik Schleife zuer Wiederholung von Switch-Case


von Francis C. (fchaleunguem)


Angehängte Dateien:

Lesenswert?

Hoi Z'me,

wie kann ich den inneren Switch-Case-schleife wiederholen, ohne jedes 
Mal zum Eingabenbeginn zu springen?

anbei das ganze Programm und hier unten ist der Abschnitt-Code.
1
                case '1':   printf("\nWahl eines wachsenden Balkens auf dem Terminal-Bildschirm darstellen\n");
2
                            printf("Bitte die Position des Balkens waehlen: \n");
3
                            printf("\t0) senkrecht wachsend\n");
4
                            printf("\t1) waagerecht wachsend\n");
5
                            printf("Ihre Wahl: ");
6
                            //Warten auf Eingabe
7
                            wahl2 = getchar();
8
                            printf("%c", wahl2);
9
                            do 
10
                            {
11
                                //Auswertung des Tastendrucks fuer das zweite Auswahl-Menue
12
                                switch(wahl2)
13
                                {
14
                                    case '0':   printf("es wird ein senkrecht wachsende Balken dargestellet\n");
15
                                                balken(2, 2, 6, 0, '*');
16
                                                break;
17
18
                                    case '1':   printf("es wird ein waagerecht wachsende Balken dargestellet\n");
19
                                                balken(2, 2, 6, 1, '*');
20
                                                break;
21
22
                                    default:    printf("Leider falsche Eingabe!");
23
                                                printf("\nBitte Taste 0 oder 1 waehlen: ");
24
                                                wahl2 = getchar();
25
                                                printf("%c", wahl2);
26
                                                break;
27
                                }
28
                            }while((wahl2=!0x30)||(wahl =!0x31));
29
                            
30
                            break;

Ich freue mich auf die Verbesserungen/Anregungen...

Vielen Dank im Voraus

von DPA (Gast)


Lesenswert?

Francis C. schrieb:
> Switch-Case-schleife

Es gibt keine Switch-Case-schleife. Es gibt schleifen, und es gibt 
switch-case. Hier ist deine Schleife eine do-while schleife, also "do 
statement while(expression);", und dein switch-case ist, nunja, das 
"switch(expression){case constant: statement ...}" ding halt. Die Dinger 
sind übrigens auch gültige statements. Packe also einfach ne schleife 
dort rein, wo du sie brauchst.

von Toby P. (Gast)


Lesenswert?

Francis C. schrieb:
> wie kann ich den inneren Switch-Case-schleife wiederholen, ohne jedes
> Mal zum Eingabenbeginn zu springen?

Das machst du doch ;-). Wenn wahl2 0 oder 1 ist kommst du nie aus der 
Schleife raus.

Das einlesen im default macht imo keinen Sinn, warum machst du es nicht 
klassisch?

1. Code einlesen
2. Code bearbeiten
3. Nach 1. gehen

von NichtWichtig (Gast)


Lesenswert?

Francis C. schrieb:
> Hoi Z'me,
>
>                             }while((wahl2=!0x30)||(wahl =!0x31));

was genau soll hier passieren ?

von Francis C. (fchaleunguem)


Lesenswert?

DPA schrieb:
> Es gibt keine Switch-Case-schleife. Es gibt schleifen, und es gibt
> switch-case. Hier ist deine Schleife eine do-while schleife, also "do
> statement while(expression);", und dein switch-case ist, nunja, das
> "switch(expression){case constant: statement ...}" ding halt. Die Dinger
> sind übrigens auch gültige statements. Packe also einfach ne schleife
> dort rein, wo du sie brauchst.

da gebe ich dir recht. Da muss ich aufpassen!!!
Aber in wie fern soll ich "einfach ne Schleife reinpacken, wo ich 
braeuchte"?

NichtWichtig schrieb:
> was genau soll hier passieren ?

dass nur die Zahlen 0 und 1 einzugeben sind, und falls nicht, dann soll 
es in Schleife bleiben.
Mein Problem ist, dass ich immer zum Hauptmenue springe:
1
 /* Bildschirm-Überschrift */
2
        printf("\nDieses Programm zeichnet folgendes auf dem Terminal-Bildschirm, ...\n");
3
        printf("=====================================================================\n\n");
4
        printf("\t1)einen wachsenden Balken \n");
5
        printf("\t2)verschiedene rechtecke.\n");
6
7
        printf("Bitte, Ihr Wahlprogramm: ");

Aber ich will hier drin bleiben, sobald ich eine falsche Eingabe machen:
1
 case '1':   printf("\nWahl eines wachsenden Balkens auf dem Terminal-Bildschirm darstellen\n");
2
                            printf("Bitte die Position des Balkens waehlen: \n");
3
                            printf("\t0) senkrecht wachsend\n");
4
                            printf("\t1) waagerecht wachsend\n");
5
                            printf("Ihre Wahl: ");
6
                            //Warten auf Eingabe
7
                            wahl2 = getchar();
8
                            printf("%c", wahl2);

Toby P. schrieb:
> Das einlesen im default macht imo keinen Sinn, warum machst du es nicht
> klassisch?
>
> 1. Code einlesen
> 2. Code bearbeiten
> 3. Nach 1. gehen

wenn du meinst von der Funktion goto() sprichst, dann haben wir sie noch 
nicht eingesetzt und duerfen wir es nicht...
Nichtsdestotrotz kannst du mir ein bildliches Beispiel geben?

von Einer K. (Gast)


Lesenswert?

Francis C. schrieb:
> Aber in wie fern soll ich "einfach ne Schleife reinpacken, wo ich
> braeuchte"?

Wenn man eine benötigt, dann verwendet man eine.
Ein überflüssige Schleife ist eine böse Schleife.


---

Wenn man dein Problem etwas abgehobener betrachtet, dann möchtest du 
einen Eingabedatenstrom untersuchen und in Abhängigkeit davon 
irgendwelche Aktionen auslösen.

Die Standard Lösung ist ein Parser.
Und dieser ist in der Regel ein endlicher Automat.

Mein Tipp lautet also:
Lerne endliche Automaten zu bauen.


----
Natürlich ist goto nicht der Hammer für alle Probleme.
Aber verbieten muss ja auch nicht sein.

von Klaus R. (klara)


Lesenswert?

Dann schreib doch eine Funktion.
mfg Klaus

von DPA (Gast)


Lesenswert?

Francis C. schrieb:
> dass nur die Zahlen 0 und 1 einzugeben sind, und falls nicht, dann soll
> es in Schleife bleiben.

Ach so, dann ist die Schleife schon am richtigen Ort.
Die Bedingung scheint falsch zu sein. (wahl2=!0x30)||(wahl =!0x31), 
!0x30 ist 0. Bleibt also (wahl2=0)||(wahl=0), bzw. wahl2=wahl=0. Hatte 
ich ganz übersehen, sind ja nur 2 Zeichen vertauscht. Ich nehme an, du 
willst (wahl2!=0x30)&&(wahl!=0x31) oder (wahl2!='0')&&(wahl!='1'), oder 
auch !(wahl2=='0' || wahl=='1').

Ich würde das zwar dann eher so schreiben:
1
printf("Ihre Wahl: ");
2
while(true)
3
{
4
  //Auswertung des Tastendrucks fuer das zweite Auswahl-Menue
5
  wahl2 = getchar();
6
  printf("%c", wahl2);
7
  switch(wahl2)
8
  {
9
    case '0':  printf("es wird ein senkrecht wachsende Balken dargestellet\n");
10
               balken(2, 2, 6, 0, '*');
11
               break;
12
13
    case '1':  printf("es wird ein waagerecht wachsende Balken dargestellet\n");
14
               balken(2, 2, 6, 1, '*');
15
               break;
16
17
    default:  printf("Leider falsche Eingabe!");
18
              printf("\nBitte Taste 0 oder 1 waehlen: ");
19
              continue; // Nochmal von anfang an!
20
  }
21
  break; // Fertig
22
}

von Michael Gugelhupf (Gast)


Lesenswert?

NichtWichtig schrieb:
> Francis C. schrieb:
>> Hoi Z'me,
>>
>>                        }while((wahl2=!0x30)||(wahl =!0x31));
>
> was genau soll hier passieren ?

Na ja, ist halt mehrfach falsch. wahl soll wahrscheinlich wahl2 sein
1
                          } while((wahl2 =! 0x30) || (wahl2 =! 0x31));
Das kann man umschreiben zu
1
                          } while(!((wahl2 == 0x30) && (wahl2 == 0x31)));

Dann sieht man besser dass die Schleifenbedingung verpfuscht ist.

Dazu der Test auf ASCII-Codes statt auf ein Char-Literal ...

von Daniel (Gast)


Lesenswert?

Noch ein Hinweis:
Das letzte "break" in deiner äußeren Schleife kannst du weglassen, da es 
nie erreicht wird. Schau mal, wie du bei deinem Compiler Warnings 
anzeigen lassen kannst. Ein guter Compiler meldet dir unerreichbaren 
Code.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Arduino Fanboy D. schrieb:
> Mein Tipp lautet also:
> Lerne endliche Automaten zu bauen.
Endliche Automaten (oder FSM) sind die einzig nachvollziehbare Art, ein 
Programm dazu zu bringen, mehrere Sachen "gleichzeitig" zu tun.
Es wäre m.E. das Erste, was man beim Programmieren lernen sollte:
- die Hauptschleife wird immer so schnell wie möglich durchlaufen, es 
wird nirgends (mehr als ein paar µs) gewartet, schon gar nicht auf eine 
Beutzereingabe oder einen Enschalter oder sonstwas
- (Sensor-)Eingänge werden am "Anfang" der Schleife in ein 
Eingangsprozessabbild eingelesen und nicht "direkt vom Pin" bearbeitet 
(denn sonst sieht die erste Hälfte des Programms evtl. einen anderen 
Pegel als die zweite Hälfte, das gibt kuriose Effekte)
- (Aktor-)Ausgänge werden nicht sofort geschrieben, sondern in einem 
Ausgangsabbild gespeichert und am "Ende" der Schleife ausgegeben (denn 
sonst kann es sein, dass im Programmverlauf der Ausgang "glitcht"

Übrigens:
Ein Schlosser, der eine SPS programmiert, dabei Zustände in Merkern 
speichert und damit Schrittketten aufbaut, verwendet Finite 
Zustandsautomaten, ganz ohne dass er es weiß. So kompliziert kann das 
Thema also wohl nicht sein...  ;-)

Beitrag #6159716 wurde von einem Moderator gelöscht.
von Joerg (Gast)


Lesenswert?

In diesem Teil
1
((wahl2=!0x30)||(wahl =!0x31));

sollte das Ausrufezeichen vor dem Gleichheitszeichen stehen
1
((wahl2!=0x30)||(wahl !=0x31));

von leo (Gast)


Lesenswert?

Joerg schrieb:
> ((wahl2!=0x30)||(wahl !=0x31));

Syntax ist dann ok, die Logik immer noch nicht.

leo

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Warum nicht einfach natürlichsprachlich:
tuwas solange taste ungleich 0 und taste ungleich 1.
1
 
2
   while( wahl2!='0' && wahl2!='1' );

Schlauhubers würden sich die wahl2 Variable aber einfach ein wenig 
zurechtbiegen. Dann lautet die vom Original abgeleitete und im Ablauf 
ein wenig verbesserte Abfrage so:
1
                case '1':   printf("\nWahl eines wachsenden Balkens auf dem Terminal-Bildschirm darstellen\n");
2
                            printf("Bitte die Position des Balkens waehlen: \n");
3
                            printf("\t0) senkrecht wachsend\n");
4
                            printf("\t1) waagerecht wachsend\n");
5
                            printf("Ihre Wahl: ");
6
7
                            do 
8
                            {
9
                                //Warten auf Eingabe
10
                                wahl2 = getchar();
11
                                printf("%c", wahl2);
12
                                //Auswertung des Tastendrucks fuer das zweite Auswahl-Menue
13
                                switch(wahl2)
14
                                {
15
                                    case '0':   printf("es wird ein senkrecht wachsende Balken dargestellet\n");
16
                                                balken(2, 2, 6, 0, '*');
17
                                                break;
18
19
                                    case '1':   printf("es wird ein waagerecht wachsende Balken dargestellet\n");
20
                                                balken(2, 2, 6, 1, '*');
21
                                                break;
22
23
                                    default:    printf("Leider falsche Eingabe!\nBitte Taste 0 oder 1 waehlen: ");
24
                                                wahl2 = 0;
25
                                                break;
26
                                }
27
                            } while ( wahl2==0 );

: Bearbeitet durch Moderator
von Francis C. (fchaleunguem)


Angehängte Dateien:

Lesenswert?

DPA schrieb:
> Ich würde das zwar dann eher so schreiben:

bei falscher Eingabe bleibt der Code bei dieser Eingabe und tut nichts 
weiter
1
printf("\nBitte Taste 0 oder 1 waehlen: ");

Michael Gugelhupf schrieb:
> Das kann man umschreiben zu                          } while(!((wahl2 ==
> 0x30) && (wahl2 == 0x31)));

leider dreht sich das ganze im Kreis der Switch-case und kommt nicht 
mehr heraus-->Ausgabebild (Ergebnis) angehaengt.

Klaus R. schrieb:
> Dann schreib doch eine Funktion.

ich hatte daran gedacht, aber ich muss nur genau diese Funktionen 
programmieren, Nichts mehr. Aber dein Vorschlag werde ich separat 
machen, nur wenn ich das in Main nicht mal hinbekommen, dann 
wahrscheinlich als separate Funktion auch nicht.

[MOD: Zitat von Pauls Post gelöscht]

Fazit:
ich werde den Code beim "Alten" lassen,

DANKE trotzdem!

: Bearbeitet durch Moderator
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Francis C. schrieb:
> Nicht schoen!
Das war Paul. Der hat Hausverbot. Du kannst dir denken, warum.

> leider dreht sich das ganze im Kreis der Switch-case und kommt nicht
> mehr heraus-->Ausgabebild (Ergebnis)
Ja, klar, weil du dort ja auch nicht mehr die Taste einliest, diese also 
immer den alten Wert behält und die Schleife nicht abgebrochen wird, 
weil die Abfrage im while() nicht passt.
Ich habe in meinem Codeschnipsel die Position des Zeichen-Einlesens 
dorthin gerückt, wo es tatsächlich hingehört: direkt vor die Auswertung.

von Einer K. (Gast)


Lesenswert?

Francis C. schrieb:
> Nicht schoen! ich habe es als Witz wahrgenommen, denn er antwortete auf
> ein genauso zuvor witziges Schreiben.

Das war kein Witz.
Das war die emotionale Reaktion eines Betroffenen!

Die Betroffenheit ergibt sich nur aus den eigenen alten 
Erfahrungen/Vorstellungen.
Die emotionale Reaktion ist also eine ganz individuelle.
Die muss kein anderer verstehen oder nachvollziehen können.


Ein Schlosser, mit hinreichend Selbstwert, muss nichts von "endlichen 
Automaten" gehört haben. Und einem solchen macht es auch nichts aus, 
wenn man ihm mitteilt, dass es einen Fachbegriff für das gibt, was er da 
manchmal tut.

von Teo D. (teoderix)


Lesenswert?

Lothar M. schrieb:
> Dann lautet die vom Original abgeleitete und im Ablauf
> ein wenig verbesserte Abfrage so:

Sieht ja grausig aus....

Löst Euch doch mal von "Eingabe == Case" und macht ne Ablaufsteuerung 
draus. Keine extra schleife, lieber ein extra Case einfügen....

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Teo D. schrieb:
> Sieht ja grausig aus....
Ganz meine Worte.
Ich würde da wie gesagt eine FSM draus machen. Da ist die Eingabe kein 
Zustand, sondern dient nur der Weiterschaltung in Richtung Ziel.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Francis C. schrieb:
> wie kann ich den inneren Switch-Case-schleife wiederholen, ohne jedes
> Mal zum Eingabenbeginn zu springen?

ich denke, deine frage sollte eher sein - wie kann ich programmieren 
lernen, weil das kannst du nicht! ausser copy/past hast du noch nichts 
begriffen.

daher erstmal das thema belesen/studieren - ja, kostet richtig zeit, und 
dann im KLEINEN mal rumprobieren, usw. ...

aber hier wie immer nur fragen stellen, die schon unklar sind und selbst 
dann die antworten nicht vertehen führt direkt zum hirntot.
ok, toter als tot geht ja nicht mehr ...


mt

: Bearbeitet durch User
von A.S. (Gast)


Lesenswert?

Ich glaube, folgendes würde noch nicht thematisiert:

Beide switch-case sind durch if bzw. while umschlossen, die nochmals das 
gleiche abfragen.

Das ist unnötig und gefährlich.

Genau dafür nutzt man das Default.

case '1': mache dies; continue;
case '2': mache das; continue;
default: break;

Beitrag #6160583 wurde von einem Moderator gelöscht.
von Dietrich L. (dietrichl)


Lesenswert?

Apollo M. schrieb:
> ich denke, deine frage sollte eher sein - wie kann ich programmieren
> lernen

Wie wäre es, hierzu die gute alte Methode "Programmablaufplan" oder 
"Flussdiagramm" zu verwenden?

Da kann schnell und übersichtlich mit Bleistift und Papier den Ablauf 
skizieren und sehen, wo was gemacht werden muss und wo es eventuell 
klemmt. Dazu reicht auch erstmal ein Grobplan.
Das Schöne daran ist auch: es ist unabhängig von der Programmiersprache, 
man muss in dieser Phase noch gar kein "C" können ;-)

von Einer K. (Gast)


Lesenswert?

Dietrich L. schrieb:
> Wie wäre es, hierzu die gute alte Methode "Programmablaufplan" oder
> "Flussdiagramm" zu verwenden?

Zustandsdiagramme sind auch manchmal hilfreich. Gerade beim 
Automatenbau.

Oder gar ein Datenfluss Diagramm....
Die Dinger werden all zu gerne unterschätzt.

von Garstiger Gast (Gast)


Lesenswert?

Apollo M. schrieb:

> daher erstmal das thema belesen/studieren - ja, kostet richtig zeit, und
> dann im KLEINEN mal rumprobieren, usw. ...

Gilt auch für deine Rechtschreibung!

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.