grrr schrieb:> Nein. LOGISCHES Oder verwenden, außerdem ist die Bedingung immer wahr.
Beides hat nichts mit der Syntax zu tun, und nur das war gefragt.
Tobias Mehrl schrieb:> Gut Syntaktische ist es korrekt. Warum aber kommt immer wahr raus? Das> verstehe ich nicht... Das Problem hab ich nämlich jetzt grad!
Die Bedingung wird nur falsch, wenn das Zeichen sowohl + als auch - ist.
Gleichzeitig.
|| so geht's auch nicht. Hab ich vorher schon ausprobiert.
Was is mit isalpha()? Hab's grad ausprobiert, aber geht auch nicht. Gut,
ich hab's so geschrieben:
while(!isalpha(x[i])
{
};
Tobias Mehrl schrieb:> Wie bekomm ich dann das entweder oder als Bedingung in den Schleifenkopf> rein? Mit dem | oder || geht's ja anscheinend nicht...
Ein "entweder oder" wäre
while((str_komplett[i] != '+') != (str_komplett[i] != '-'))
aber ich bezweifle, dass du das wirklich meinst.
Ich biete ein "und" an Stelle des "oder".
A. K. schrieb:> @cproper: Diese while() Variante ist zwar gebräuchlicher,> aber genauso falsch.
Das kannst du so nicht sagen.
Vielleicht will er ja den Rumpf immer ausgeführt haben?
Dann wäre es absolut korrekt :-)
Tobias Mehrl schrieb:> Wie bekomm ich dann das entweder oder als Bedingung in den Schleifenkopf> rein? Mit dem | oder || geht's ja anscheinend nicht...
Och Mensch, denken!
while( (var!='+') && (var!='-') )
{
tu_was_sinnvolles();
}
Etwas boolsche Algebra macht daraus
while( ! ( (var=='+') || (var=='-') ) )
{
tu_was_sinnvolles();
}
@... (Gast) :
Gut, aber mit passendem #define davor bekommst du ziemlich
alles syntaktisch korrekt hin, und sei es nur indem man alles
wegdefiniert zu nichts :-)
Wenn ich nun das hier
while(isdigit(x))
{
};
schreibe, dann bekomm ich wenn x erfüllt ist einen von 0 verschiedenen
Wert. D.h. entweder -1 oder 1. Wie bekomm ich das nun hin, dass ich
immer einen fest definierten Zustand von einer glatten +1 krieg?
Nein es soll kein c++ sein...
Ich möchte eigentlich einen String auf korrekt Eingabe prüfen. An erster
Stelle muss einzelne Zahl stehen an zweiter stelle mus ein D stehen an
dritter Stelle muss wieder eine einzelne Zahl stehen an vierter Stelle
entweder ein + oder ein - und an fünfter Stelle muss wieder ein einzelne
Zahl stehen.
Wenn bei der Eingabe davon abgewichen wird, muss eine Fehlermeldung
ausgegeben werden.
Das soll ich machen
Tobias Mehrl schrieb:> Zahl ... Zahl
Ziffer meinst du wohl.
Eigentlich kannst du diesen ganzen Test mit einem einzigen
Aufruf von sscanf() erschlagen.
Es übt natürlich auch, das alles Zeichen für Zeichen zu machen,
dem will ich nicht im Wege stehen.
aber: wie mach ich es, wenn ich jeden Fehler einzeln erkannt haben will?
Ausgabe in der Art:
-Stelle 1 ist falsch
-Stelel 2 ist falsch
-Stelle 5 ist falsch
Tobias Mehrl schrieb:> Ich möchte eigentlich einen String auf korrekt Eingabe prüfen. An erster> Stelle muss einzelne Zahl stehen an zweiter stelle mus ein D stehen an> dritter Stelle muss wieder eine einzelne Zahl stehen an vierter Stelle> entweder ein + oder ein - und an fünfter Stelle muss wieder ein einzelne> Zahl stehen.
Also ein simpler Einzeiler ;-)
Vergiss' cctype und string.h und geh noch ein letztes mal mit Deinen
Freunden aus und verabschiede Dich bevor Du das Deinem Lehrer
vorlegst...
printf((x[0]>='0' && x[0]<='9' && x[1]=='D' && x[2]>='0' && x[2]<='9' &&
(x[3]=='+' || x[3]=='-') && x[4]>='0' && x[4]<='9' && !x[5]) ? "Alles
ok" : "Eingabefehler");
Aber um auch ernstgemeinte Ratschläge zu geben: Eine Schleife brauchst
du hier nicht wirklich, dafür aber cctype und string.h wenn du es
vernünftig machen willst.
Überprüf die Länge der Eingabe als erstes (mit strlen)
Danach erst prüfe den Rest:
- erst auf die Ziffern
- dann auf das 'D'
- dann auf + oder -
Du mußt auch nicht alles in eine Schleife setzen. Setze am Anfang eine
Kontrollvariable auf 1 und bei einer fehlgeschlagenen Prüfung in den
einzelnen Tests auf 0
Wenn eine Prüfung fehlschlägt (Länge des Strings, oder z.B. Ziffer an x.
Stelle) dann brauchst (bzw. DARFST) Du die restlichen Tests NICHT mehr
durchführen, z.B. wenn strlen==2 dann mach keinen Test an x[4] (hinter
dem Stringende). Das macht bei fest dimensionierten Strings a la "char
eingabe[20];" sicher nichts aus, dürfte aber Punktabzug geben.
Torsten K. schrieb:> Überprüf die Länge der Eingabe als erstes (mit strlen)
nicht nötig bei meinem Vorschlag, weil das Programm ein zu
frühes Stringende auch als Fehler erkennt (nebenbei).
Für die erste Version schämst du dich hoffentlich etwas,
sowas macht man nicht in der Öffentlichkeit :-)
Also langsam:
Ich geb den String ein. Gut.
Jetzt stehen evtl. Fehler an den Stellen. Die möchte ich nun
identifizieren und ALLE Eingabefehler der Reihe nach ausgeben. Wie mache
ich das?
Klaus Wachtler schrieb:> Für die erste Version schämst du dich hoffentlich etwas,> sowas macht man nicht in der Öffentlichkeit :-)
Man kann sowas sogar schachteln ;-)
"Lohnt es sich nach dem ersten Fehler noch die restlichen auszugeben?"
Eigentlich nicht; meiner Meinung nach. Aber ich weiß nicht recht was in
meiner Aufgabe da genau verlangt ist. Das ist sehr schwammig formuliert.
Hier der Auszug: "Quittieren Sie bitte Eingaben, die nicht dem obigen
Format entsprechend, mit einer Fehlermeldung." Keine Ahnung ob man nun
alle Fehler ausgeben soll, oder ob nur der erste reicht...
Das ist eine Standard-man-Page von Unix bzw. Linux.
Die sind auch alle im Internet zu finden, falls du mit Windows
arbeitest.
Falls du Linux hast, sollten die alle da sein (notfalls das passende
Paket nachinstallieren).
Der Vorteil der man-Pages gegnüber z.B. der Onlinehilfe im
VisualStudio o.ä. ist, daß man klar sieht, was zu welchem Standard
gehört (hier: ISO-C89 und ISO-C99) und deshalb merkt, wann man
nicht mehr portabel programmiert.
Tobias Mehrl schrieb:> Jetzt stehen evtl. Fehler an den Stellen. Die möchte ich nun> identifizieren und ALLE Eingabefehler der Reihe nach ausgeben. Wie mache> ich das?
Das steht doch alles schon im Beitrag von Klaus, siehe
Datum: 03.12.2010 21:36
Aber um Deine Frage "Die möchte ich nun identifizieren und ALLE
Eingabefehler der Reihe nach ausgeben. Wie mache ich das?" doch noch zu
beantworten:
Du prüfst auf Fehler und falls es falsch ist, dann gib eine
entsprechende Meldung aus.
int errmask = ((x[0]<'0'||x[0]>'9')?1:0) || ((x[1]!='D')?2:0) ||
((x[2]<'0'|| x[2]>'9')?4:0) || ((x[3]!='+'&&x[3]!='-')?8:0) ||
((x[4]<'0'||x[4]>'9')?16:0) || ((x[5])?32:0)
if (errmask & 1)
printf("Erstes Zeichen keine Zahl.");
if (errmask & 2)
printf("Zweites Zeichen kein 'D'.");
if (errmask & 4)
printf("Drittes Zeichen keine Zahl.");
if (errmask & 8)
printf("Viertes Zeichen kein + oder -.");
if (errmask & 16)
printf("Fünftes Zeichen keine Zahl.");
if (errmask & 32)
printf("Länge der Eingabe ungleich 5 Zeichen.");
if (!errmask)
printf("Alles ok.");
Statt der ?: hättest du es auch mit << etwas kompakter schreiben können
:-)
Richtig ist es, aber für einen Einsteiger vielleicht etwas hm, naja,
pädagogisch forsch?
Klaus Wachtler schrieb:> Statt der ?: hättest du es auch mit << etwas kompakter schreiben können> :-)
Ich war mir da jetzt nicht sicher ob ein logisches TRUE immer als binäre
"1" definiert ist. Ich meine früher mal gesehen (erlebt) zu haben, das
TRUE "-1" war, also alle Bits gesetzt. Bin mir da aber nicht mehr
sicher, ob das nun C war. Könnte der Inline-Assembler im BASIC vom
damaligen Acorn RiscPC gewesen sein.
Klaus Wachtler schrieb:> Richtig ist es, aber für einen Einsteiger vielleicht etwas hm, naja,> pädagogisch forsch?
Das war schon absicht (ich weiß das es für Einsteiger unlesbar ist,
selbst ich finde es grottig..). Irgendwie hatte ich das Gefühl das er
sich alles vorkauen läßt, und da mache ich dann mal sowas aus frust.
Tipps gab es hier und im Nachbarthread reichlich. Vielleicht bin ich
auch einfach nur zu gestreßt und empfindlich....
dann muss man hier etwas sagen:
Hüte dich davor, da mit Alltagswissen ranzugehen. Wir Menschen sind im
Alltag unglaublich schlampig, wenn es um die Verwendung von UND und ODER
geht.
In solchen Fällen empfiehlt es sich immer das ganze mit ein paar
Beispielen durchzuspielen.
Annahme:
Das Zeichen sei 'A'
'A' ist nicht gleich '+' die Bedingung ist also wahr
und die Schleife wird wiederholt
Das Zeichen sei '+'
Es ist nicht wahr, dass '+' nicht gleich '+' sei. Dieser Teil der
Bedinung ist daher falsch. Aber
Es ist wahr, dass '+' nicht gleich '-' ist. Dieser Teil ist daher wahr.
Da sind daher 2 Teilbedingungen, die eine wahr die andere falsch. Und
verodert ergibt das nun mal wahr. -> die Schleife wird ausgeführt
Das Zeichen sei '-'
'-' ist nicht gleich '+'. Diese Bedingung ist also wahr
und daher wird die Schleife wiederholt.
Seltsam. Egal welches Zeichen man zum Testen nimmt, die komplette
Bedingung ist immer wahr. Völlig egal bei welchem Zeichen.
Das heist die umgangssprachliche saloppe Formulierung "Ich will die
Schleife wiederholen, solange das Zeichen nicht '+' oder nicht '-' ist"
ist logisch gesehen Unsinn. Das eigentlich interessante dabei ist, dass
jeder dem du das erzählst unmittelbar versteht was du meinst und (wenn
er selber Computer spielt) das richtige tut.
Daher Vorsicht! Bei Ausdrücken mit NICHT und UND und/oder ODER immer
einfach ein paar Variablenwerte annehmen und den Ausdruck durchspielen!
Und zwar so wie er dort stehen, völlig wertfrei, neutral und
unvoreingenommen. Die Intuition ist da nämlich sehr trügerisch.
Torsten K. schrieb:> Ich war mir da jetzt nicht sicher ob ein logisches TRUE immer als binäre> "1" definiert ist.
Alle logischen Operationen in C liefern 0 (wenn nicht erfüllt)
oder +1 (wenn erfüllt), nie etwas anderes.
Das war auch schon immer so.
Deshalb kann man so schön damit rechnen :-)
Torsten K. schrieb:> Das war schon absicht (ich weiß das es für Einsteiger unlesbar ist,> selbst ich finde es grottig..). Irgendwie hatte ich das Gefühl das er> sich alles vorkauen läßt, und da mache ich dann mal sowas aus frust.> Tipps gab es hier und im Nachbarthread reichlich. Vielleicht bin ich> auch einfach nur zu gestreßt und empfindlich....
Naja, manchmal schwer zu sagen.
Aber bei Tobias Mehrl habe ich schon den Eindruck, daß er sich
damit beschäftigt.
Im Gegensatz zu dem hier: Beitrag "ATtiny2313 Programmieren"