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
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.
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
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");
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?
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.
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");
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 ...
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.
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... ;-)
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: ");
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!
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.
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.
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....
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.
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
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;
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 ;-)
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.
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!