![]() |
Austauschen einer Case Anweisung mit einer Sinnvolleren
Hallo Leute,
Ich bin dabei ein Programm zu schreiben, was ein Menü ausgibt in dem man auswählen kann in einem vorher eingegebenem String die Operatoren in Strings umzuwandeln also + = plus etc. Nun habe ich es mit einer Case Anweisung probiert für jeden einzelnen Operator, jedoch besteht jetzt das Problem, das die Überprüfung endet sobald ein Operator gefunden und umgetauscht wurde. Ich komme leider nicht drauf wie ich das anders erstellen kann sodass das Programm die Überprüfung für die Operatoren nicht beendet sobald eins gefunden wurde. Würde mich sehr freuen wenn mir jemand auf die Sprünge helfen kann :-D.
Delphi-Quellcode:
{$APPTYPE CONSOLE}
{$R+,Q+,X-} uses System.SysUtils; var abbruch : Boolean; menueEingabe : Char; satz : String; laufVariable,anzahlPlus,anzahlMinus,anzahlMal,anzahlGeteilt : Word; plus,minus,mal,geteilt : String; begin abbruch := (menueEingabe = upcase('x')) or (menueEingabe = 'x'); plus := ' plus '; minus := ' minus '; mal := ' mal '; geteilt := ' geteilt '; repeat writeln('A) Satz eingeben'); writeln('B) Anzahl Operatoren im Satz bestimmen'); writeln('C) Operatoren in Satz ausschreiben'); writeln('D) Alle Wörter entfernen, die keinen Operator erhalten'); writeln('X) Ende'); readln(menueEingabe); case menueEingabe of 'A','a' : readln(satz); 'B','b' : begin if length(satz) > 0 then begin anzahlPlus := 0; anzahlMinus := 0; anzahlMal := 0; anzahlGeteilt := 0; for laufVariable := 1 to length(satz) do begin case satz[laufVariable] of '+' : inc(anzahlPlus); '-' : inc(anzahlMinus); '*' : inc(anzahlMal); '/' : inc(anzahlGeteilt); end; end; writeln(anzahlPlus,' + und ',anzahlMinus,' - und ',anzahlMal,' * und ',anzahlGeteilt,' / im Satz gefunden'); end else writeln('Eingabe ungültig!'); end; 'C','c' : begin if length(satz) > 0 then for laufVariable := 1 to length(satz) do begin case satz[laufVariable] of '+' : begin delete(satz,laufVariable, 1); insert(plus,satz,laufVariable); end; '-' : begin delete(satz,laufVariable,1); insert(minus,satz,laufVariable); end; '*' : begin delete(satz,laufVariable,1); insert(mal,satz,laufVariable); end; '/' : begin delete(satz,laufVariable,1); insert(geteilt,satz,laufVariable); end; end; end; writeln(satz); end; 'D','d' : begin if length(satz) > 0 then writeln('Richtig D') else writeln('Eingabe ungültig!'); end; 'X','x' : abbruch := TRUE else writeln('Eingabe ist ungültig!'); end; until (abbruch); readln; end. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Nicht geprüft, aber da Du den Satz ja veränderst würde ich das so lösen:
Also vom Ende her untersuchen deshalb anstatt einer for eine while loop
Delphi-Quellcode:
'C','c' : begin
laufVariable := length(satz); while laufvariable > 0 do begin case satz[laufVariable] of '+' : begin delete(satz,laufVariable, 1); insert(plus,satz,laufVariable); end; '-' : begin delete(satz,laufVariable,1); insert(minus,satz,laufVariable); end; '*' : begin delete(satz,laufVariable,1); insert(mal,satz,laufVariable); end; '/' : begin delete(satz,laufVariable,1); insert(geteilt,satz,laufVariable); end; end; // End case dec(laufvariable); end; writeln(satz); end; |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Du hast deine Variablen nicht initialisiert.
Delphi-Quellcode:
Du weist der Variable "abbruch" beim Programmstart einen Wert zu, der von "menueEingabe" abhängt, was wiederum ebenfalls nicht initialisiert ist.
var
abbruch : Boolean; menueEingabe : Char; begin abbruch := (menueEingabe = upcase('x')) or (menueEingabe = 'x'); Schreibe diese Zeile (abbruch := ...) nach " readln(menueEingabe);". Dann wird in in jedem Durchlauf ermittelt, ob das Programm verlassen werden soll, oder nicht... Alternativ zumindest die Variable richtig initialisieren, damit Abbruch:=False hat (auch nach ReadLn), denn du verwendest ja (auch) die Case-Anweisung zum Auswerten von X. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Zur Vereinfachung könntest Du
Delphi-Quellcode:
gegen
ReadLn(menueEingabe)
Delphi-Quellcode:
tauschen, dann wären die Stellen wie
ReadLn(UpperCase(menueEingabe));
Delphi-Quellcode:
einfacher, nämlich nur
'B','b' : begin
...
Delphi-Quellcode:
Gruß, Andreas
'B' : begin
... |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Ähhh nein?
Das ist ein VAR-Parameter, da geht keine Funktion drumrum, schon garkeine mit String, wo es aber ein Char sein soll.
Delphi-Quellcode:
Aber hier sehe ich eh keinen Grund das Zwanghaft kürzen zu wollen.
menueEingabe := UpperCase(menueEingabe)[1];
// oder direkt case UpperCase(menueEingabe)[1] of Zitat:
Und warum überhaupt unnötig ein WHILE, anstatt einem FOR?
Delphi-Quellcode:
for laufVariable := Length(satz) downto 1 do
if satz[laufVariable] in ['+', '-', '*', '/'] then begin delete(satz, laufVariable, 1); case satz[laufVariable] of '+' : insert(plus, satz, laufVariable); '-' : insert(minus, satz, laufVariable); '*' : insert(mal, satz, laufVariable); '/' : insert(geteilt, satz, laufVariable); end; end;
Delphi-Quellcode:
Und nun mal ganz im Ernst ...
const ZeichenZuText: array['*'..'/'] of string = (mal, plus, '', minus, '', geteilt);
for laufVariable := Length(satz) downto 1 do if satz[laufVariable] in ['+', '-', '*', '/'] then begin delete(satz, laufVariable, 1); insert(ZeichenZuText[satz[laufVariable]], satz, laufVariable); end;
Delphi-Quellcode:
satz := ReplaceStr('+', plus);
satz := ReplaceStr('-', minus); satz := ReplaceStr('*', mal); satz := ReplaceStr('/', geteilt); // oder for C := Low(ZeichenZuText) to High(ZeichenZuText) do if ZeichenZuText[C] <> '' then satz := ReplaceStr(C, ZeichenZuText[C]); |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Vielen Dank Leute, das hat mir sehr weitergeholfen:-D
|
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Ich versuche jetzt gerade für Menüpunkt D eine Anweisung zu erstellen die alle Wörter in denen kein Operator enthalten ist löscht.
Bsp.: (Gu+en Tag) wird zu (Gu+en). Jedoch ist dies komplizierter als gedacht. Habt iht vielleicht eine Idee? Ich darf jedoch keine Arrays oder selbstgemachte Funktionen anwenden.
Delphi-Quellcode:
begin
if length(satz) > 0 then begin leerZeichen := ' '; laufVariable := 1; repeat for laufVariable := 1 to pos(leerZeichen, satz, laufVariable) do begin case satz[laufVariable] of '+': inc(anzahlPlus); '-': inc(anzahlMinus); '*': inc(anzahlMal); '/': inc(anzahlGeteilt); end; keinOperator := (anzahlPlus = 0) and (anzahlMinus = 0) and (anzahlMal = 0) and (anzahlGeteilt = 0); if keinOperator then delete(satz, laufVariable, (pos(leerZeichen, satz, laufVariable) - 1)); end; until (length(satz) = laufVariable); end |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Erst das "ganze" Wort durchgehn
und nach der Schleife wird Entschieden, ob löschen oder nicht. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
@Himitsu
Ich mache das ja schon, aber ich verstehe nicht wie ich dem Programm erklären soll das es ein wort von anfang bis ende löscht. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Gibt es mehrere Möglichkeiten.
Eine wäre z.B. Deinen Text bei jedem Leerzeichen zu splitten ( ![]() Dann hast du ein Array in dem jedes Wort einzeln steht. Dann das Array durchgehen und 1. mit pos() ( ![]() |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Zitat:
|
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
@Moombas ich darf leider keine arrays verwenden.
|
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Du gehst mit einer schleife das wort durch und kopierst jeden buchstaben in eine zwischenvariable, stöst du dabei auf einen operator setzt du eine Boolean auf true. Kommst du an ein Leerzeichen (oder das Ende des Satzes) dann schaust du: War ein Operator drin, dann kopier das wort in eine neue Variable Ergebnis. War diese Variable zuvor nicht leer, ergänze erst ein Leerzeichen und hänge dann den Wert der Zwischenvariablen dran. Ist in der Zwischenvariablen kein Operator, dann leere sie einfach. Setzte die Boolean wieder auf False. Weiter gehts.
|
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Ich gehe davon aus, das ist hier dann Schul- oder Ausbildungsaufgabe?
Denn ansonsten macht das "darf keine Arrays verwenden" keinen Sinn. Und Btw: 3 geteilt 5 liest sich komisch. Ich würde "geteilt durch" oder nur "durch" schreiben an deiner Stelle. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Delphi-Quellcode:
Falls du CharInSet nicht verwenden darfst, musst du dir das wieder in ein case umbauen.
if length(satz) > 0 then
begin OPFound := False; // Boolean-Variable noch deklarieren Laenge := 0; // Integer-Variable noch deklarieren for laufvariable := length(satz) downto 1 do begin inc(Laenge); OPFound := CharInSet(satz[laufvariable], ['+', '-', '*', '/']) or OPFound; if satz[laufVariable] = ' ' then // Vergleich auf Leerzeichen begin if not OPFound then begin Delete(satz, laufvariable, Laenge); end; OPFound := False; Laenge := 0; end; end; if not OPFound then begin Delete(satz, 1, Laenge + 1); // +1 wegen des Leerzeichens end; end; |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Zitat:
:) |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Du kannst auch eine oder verknüpfte If-Anweisung nehmen.
Case hast du doch bereits gemacht, musst es nur noch anwenden. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Zitat:
Du hast in den anderen Programmteilen bereits entsprechende Case-Strukturen drin. Der Umbau ist trivial. Du kannst dann sogar das "or OPFound" weglassen. CharInSet prüft nur, ob dein aktuelles Zeichen aus dem Satz in der Menge der Operatorzeichen enthalten ist. Wenn du für jedes Operatorzeichen einen Case-Fall erstellst, bist du im Prinzip schon fertig. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Hier ist mMn aber der Lerneffekt mit einem "if" größer, ala
if (zeichen='+') or (zeichen='-') ... then OPFound:=true; |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
So ich habs jetzt, das Programm läuft Prima, jedoch gibt es ein kleines Problem und zwar wenn man ins Menü ab oder ac oder generell einen Buchstaben nach a eingibt, wird trotzdem A ausgeführt, obwohl eigentlich gedacht war das er Eingabe ist ungültig ausgeben soll.
Habt ihr eine Idee?
Delphi-Quellcode:
{$APPTYPE CONSOLE}
{$R+,Q+,X-} uses System.SysUtils; var keinOperator, endeErreicht, operatorGefunden, leerzeichenGefunden: Boolean; menueEingabe: Char; leerZeichen: String; satz: String; laufVariable, anzahlPlus, anzahlMinus, anzahlMal, anzahlGeteilt, wortEnde: Word; // Schleife zur Ausgabe des Menüs: begin repeat writeln('A) Satz eingeben'); writeln('B) Anzahl Operatoren im Satz bestimmen'); writeln('C) Operatoren in Satz ausschreiben'); writeln('D) Alle Wörter entfernen, die keinen Operator erhalten'); writeln('X) Ende'); readln(menueEingabe); writeln; menueEingabe := upcase(menueEingabe); case menueEingabe of // Option einen Satz einzugeben: 'A': begin write('Satz eingeben: '); readln(satz); end; // Option alle Operatoren im String aufzuzählen: 'B': begin if length(satz) > 0 then begin anzahlPlus := 0; anzahlMinus := 0; anzahlMal := 0; anzahlGeteilt := 0; for laufVariable := 1 to length(satz) do begin case satz[laufVariable] of '+': inc(anzahlPlus); '-': inc(anzahlMinus); '*': inc(anzahlMal); '/': inc(anzahlGeteilt); end; end; writeln(anzahlPlus, ' + und ', anzahlMinus, ' - und ', anzahlMal, ' * und ', anzahlGeteilt, ' / im Satz gefunden'); end else writeln('Eingabe ungültig!'); end; // Option alle Operatoren im String auszuschreiben: 'C': begin laufVariable := length(satz); while laufVariable > 0 do begin case satz[laufVariable] of '+': begin delete(satz, laufVariable, 1); insert(' plus ', satz, laufVariable); end; '-': begin delete(satz, laufVariable, 1); insert(' minus ', satz, laufVariable); end; '*': begin delete(satz, laufVariable, 1); insert( ' mal ', satz, laufVariable); end; '/': begin delete(satz, laufVariable, 1); insert(' geteilt ', satz, laufVariable); end; end; dec(laufVariable); end; writeln(satz); end; // Option alle Wörter im String die keinen Operator enthalten zu löschen: 'D': begin if length(satz) > 0 then begin laufVariable := length(satz); wortEnde := length(satz); endeErreicht := TRUE; while endeErreicht do begin operatorGefunden := FALSE; wortEnde := laufVariable; leerzeichenGefunden := FALSE; repeat if ((satz[laufVariable] = '+') or (satz[laufVariable] = '-') or (satz[laufVariable] = '*') or (satz[laufVariable] = '/')) then operatorGefunden := TRUE; if (satz[laufVariable] = ' ') then begin leerzeichenGefunden := TRUE; if not operatorGefunden then delete(satz, laufVariable, (wortEnde - laufVariable + 1)); end; if (not leerzeichenGefunden and (laufVariable = 1) and not operatorGefunden) then begin delete(satz, laufVariable, (wortEnde - laufVariable + 2)); end; dec(laufVariable); if laufVariable = 0 then endeErreicht := FALSE; until ((laufVariable = 0) or leerzeichenGefunden); end; writeln(satz); end else writeln('Eingabe ungültig!'); end; end; until (menueEingabe = 'X'); end. |
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Deine Variable menueeingabe ist vom Typ char. Da passt nur ein Zeichen rein. Das Readln wird deshalb nur das erste Zeichen darin speichern können. Alles was danach kommt, wird verworfen. Wenn du deinen Fehler provozieren willst, musst du zum Beispiel "f" eingeben.
|
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Wie meinst du das mit dem provozieren ?
|
AW: Austauschen einer Case Anweisung mit einer Sinnvolleren
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz