jetzt soll ich diese aufgabe lösen:
Der Benutzer wird aufgefordert nacheinander zwei positive Dezimalzahlen
(mit jeweils
maximal 4 Dezimalstellen) einzugeben. Die Eingabe der Dezimalzahlen
erfolgt unter
Verwendung der Funktion getstring() und liefert somit zwei Strings.
• Diese beiden Strings sollen dahingehend überprüft werden ob diese
nicht zu lang sind
und ausschließlich die ASCII-Zeichen 0 bis 9 beinhalten. Wenn ja so soll
der entsprechende
Integer-Wert (unsigned short int) berechnet werden. Ansonsten soll eine
geeignete
Fehlerausgabe mit Aufforderung einer erneuten Eingabe erfolgen.
• Die zwei Dezimalzahlen sollen addiert und deren Summe in einer
Integer-Variablen
(unsigned short int) gespeichert werden. Der Summenwert soll dann
mittels putstring()
ausgegeben werden. Hierzu ist eine Umwandlung der Integer-Variablen in
einen entsprechenden
String notwendig.
• Zur Lösung der Aufgabe dürfen ausschließlich die folgenden Funktionen
verwendet
werden:
putstring(...)
getstring(...)
Andere schon bestehende Standardfunktionen, wie z.B. sprintf() oder
scanf(), sind
ausdrücklich verboten.
ich weiß einfach nicht, wie ich die einzelnen strings miteinander
vergleichen soll und wie ich es sage, dass die zeichen im ascii bereich
von 48-57 sind ?
im internet finde ich leider keine weiteren aufgaben die so ähnlich
sind.
viele grüße
kompletter C anfänger schrieb:> ich weiß einfach nicht, wie ich die einzelnen strings miteinander> vergleichen soll und wie ich es sage, dass die zeichen im ascii bereich> von 48-57 sind ?
ein string ist wie ein Array von Bytes (8bit). Da schreibt man sich eine
schleife und geht der reihe nach das Array durch. Dann kannst du jedes
Zeichen vergleichen und entscheiden ob es zwischen '0' und '9' ist.
> im internet finde ich leider keine weiteren aufgaben die so ähnlich> sind.
du sollte es ja lernen und nicht lernen wie man abschreibt.
Mit 48 oder 57 brauchst du nicht arbeiten. Schreib '0' bzw. '9'
1
if(string[i]>='0'&&string[i]<='9')
2
{// string[i] ist eine Ziffer
3
}
Zerlege das große Problem in kleinere und schreibe eigene Funktionen,
die diese kleinen Aufgaben erledigen.
Code zu atoi (Ascii TO Integer) bzw itoa solltest du aber finden
können.
Noch was anderes:
Die Funktionen getstring, copystring und appendstring wirst du von
deinem Tutor/Professeor/IT-Lehrer bekommen haben.
So wie die aufgerufen werden, geht das heutzutage gar nicht mehr, weil
sie einen Bufferoverflow generieren können.
Da gehört die Länge des Zielbereichs mit angegeben.
Vor 30 bis 20 Jahren war man da noch nicht so sensibel.
Ich würde so etwas folgendermaßen aufbauen:
1. Länge überprüfen, also wenn max. 2-Stellig auf 2 (strlen()).
2. Alle Zeichen auf Ziffern ('0'...'9') testen.
for (XYZ=0; XYZ<strlen();++XYZ) mit XYZ als Index.
3. In Zahlen umwandeln z.B. atoi () oder so und Bereich (< und >)
überprüfen.
Amateur schrieb:> 1. Länge überprüfen, also wenn max. 2-Stellig auf 2 (strlen()).> 3. In Zahlen umwandeln z.B. atoi () oder so und Bereich (< und >)
überprüfen.
> Zur Lösung der Aufgabe dürfen ausschließlich die folgenden Funktionen> verwendet> werden:> putstring(...)> getstring(...)> Andere schon bestehende Standardfunktionen, wie z.B. sprintf() oder> scanf(), sind> ausdrücklich verboten.
Hallo
danke erstmal für die hilfe
versuche mich gerade schritt für schritt ran zu tasten
habe jetzt soweit ne methode geschrieben, die überprüft ob die eingabe
des chararrays zwischen '0' und '9' liegt, leider klappt es überhaupt
nicht
kompletter C anfänger schrieb:> leider klappt es überhaupt> nicht
das hilft niemand weiter, was geht genau nicht?
> strlen(string);
darfst du denn strlen verwenden?
kompletter C anfänger schrieb:> leider klappt es überhaupt> nicht
nachtrag:
gehen einfach in Gedanken mal durch, was beim ersten zeichen-vergleich
passiert. Es wird immer ein return gemacht, die restlichen Zeichen
werden gar nicht verglichen.
Peter II schrieb:> darfst du denn strlen verwenden?
hoffe ich doch, denn sonst weiß ich nicht, wie ich den kompletten array
durchgehen soll.
als fehlercode wirft er mir das raus:
kompletter C anfänger schrieb:> Hallo>> danke erstmal für die hilfe>> versuche mich gerade schritt für schritt ran zu tasten> habe jetzt soweit ne methode geschrieben, die überprüft ob die eingabe> des chararrays zwischen '0' und '9' liegt, leider klappt es überhaupt> nicht>> [c]> #ifdef V1_Aufgabe_1>> long int checknumbers (char* string) {>> for (int i = 0 ; i<strlen(string);i++){> if (char[i]>'0' && char[i]<'9') {> return 1;
Es reicht nicht, wenn nur der erste char im erlaubten Bereich liegt.
Es müssen schon ALLE char im Array im erlaubten Bereich liegen.
Ob der String gültig war, kannst du daher erst behaupten, wenn du ALLE
char betrachtet hast.
Aber die Umkehrung kannst du sofort feststellen: Wenn einer
(irgendeiner) der char ausserhalb des erlaubten Bereichs liegt, dann
steht sofort fest, dass der STring nicht gültig sein kann.
Weiters kann man festhalten: wenn es nicht einen einzigen char gab, der
ausserhalb des zulässigen Bereiches liegt, dann müssen logischerweise
ALLE innerhalb des zulässigen Bereichs gelegen haben.
Daraus folgt: der Fall, dass ein char (irgendeiner) in deinem String
innerhalb des zulässigen Bereichs liegt, interessiert dich eigentlich
nicht. Dich interessiert vielmehr, ob irgendeiner ausserhalb liegt. Denn
dann weisst du sofort, dass der String nicht gültig sein kann. Der Fall
"liegt innerhalb und damit ist dann auch der ganze String gültig" ist
daher eigentlich ein Nebenprodukt, quasi ein Abfallprodukt, das sich
automatisch dadurch ergibt, dass der String eben nicht ungültig war,
weil irgendein Zeichen ausserhalb des zulässigen Bereiches lag.
kompletter C anfänger schrieb:> Peter II schrieb:>>>> darfst du denn strlen verwenden?>> hoffe ich doch, denn sonst weiß ich nicht, wie ich den kompletten array> durchgehen soll.
Na ja.
Dazu braucht man abeer kein strlen.
Denn in C gilt die Konvention: Ein String ist beim '\0' Zeichen zu Ende.
D.h. man muss die Länge gar nicht explizit kennen. Es reicht in der
SChleife so lange Zeichen für Zeichen zu beackern, bis man auf dieses
'\0' Zeichen stösst. Dann weiss man automatisch, dass man somit das Ende
des STrings erreicht hat. strlen macht auch nichts anderes, als das es
zählt, nach wievielen Zeichen es auf das '\0' Zeichen stösst.
kompletter C anfänger schrieb:> leider muss ich visual studio benutzen, so dass ich aus den> fehlermeldungen nicht schlau werde, in java würde das theoretisch> funktionieren
Tja, C ist nicht Java.
(Ältere Versionen von) Visual Studio können nur C89.
Das kennt nur die Variablendefiniton am Anfang der Funktion.
In der for-Schleife (wie bei dir) geht da noch nicht.
Muss es wirklich ein long int als Rückgabewert sein, wenn du nur 1 oder
-1 zurückgeben willst?
Normalerweise ist 0 falsch und 1 wahr (genauer: alles andere als 0)
kompletter C anfänger schrieb:> als fehlercode wirft er mir das raus:..\sourcen\emain.c(20): error> C2143: Syntaxfehler: Es fehlt ';' vor 'Typ'> ..\sourcen\emain.c(20): error C2143: Syntaxfehler: Es fehlt ';' vor>> leider muss ich visual studio benutzen, so dass ich aus den> fehlermeldungen nicht schlau werde, in java würde das theoretisch> funktionieren
wieso leider? Glaubst du C geht in einer anderen IDE besser?
Wenn man jetzt noch wüsste was in Zeile 20 steht, könnte man eventuell
sogar helfen.
kompletter C anfänger schrieb:> ne methode
In C heißt das FunktionKarl Heinz schrieb:> Es reicht in der> SChleife so lange Zeichen für Zeichen zu beackern, bis man auf dieses> '\0' Zeichen stösst.
Ansonsten kannst du dir auch deine eine strlen bauen, sind 7 Zeilen:
C-liker schrieb:> kompletter C anfänger schrieb:>> ne methode> In C heißt das /Funktion/>>> Karl Heinz schrieb:>> Es reicht in der>> SChleife so lange Zeichen für Zeichen zu beackern, bis man auf dieses>> '\0' Zeichen stösst.> Ansonsten kannst du dir auch deine eine strlen bauen
Im Grunde: ja
Allerdings ist es reichlich sinnlos, wenn zuerst strlen (egal welche
Version) einmal den String durchgeht um das \0 Zeichen zu finden und
dann seine Funktion nochmal durch den String durchgeht um ungültige
Zeichen zu finden.
Mann muss ja nicht mit Gewalt sinnlos Rechenzeit verplempern :-)
(das strlen als Aufruf in der Abbruchbedingung seiner for-Schleife
ignorier ich jetzt erst mal)
> Daraus folgt: der Fall, dass ein char (irgendeiner) in deinem String> innerhalb des zulässigen Bereichs liegt, interessiert dich eigentlich> nicht. Dich interessiert vielmehr, ob irgendeiner ausserhalb liegt. (...)
mit anderen worten ich sollte einfach sagen,
1
if(char[i]<='9'){
2
return1;
3
}else{
4
return0;
5
}
?
zeile 20 ist:
[c]
20: int checknumbers (char* string[]) {
21: int i =0
22: for (int i = 0 ; i<strlen(string);i++){
if (char[i]>'0' && char[i]<'9') {
return 1;
}else {
return -1;
}
}
}
kompletter C anfänger schrieb:> mit anderen worten ich sollte einfach sagen,if (char[i]<= '9') {> return 1;> }else {> return 0;> }
nein. Du darst nur ein return machen, wenn ein zeichen nicht der
Bedingung entspricht. Du machst aber mit dem else immer ein return.
kompletter C anfänger schrieb:> mit anderen worten ich sollte einfach sagen,
Nein.
Das return 1 ist falsch. Du kannst an der Stelle noch nicht sagen, ob
noch ungültige Zeichen kommen.
Und was ist das char[i] ?
Genau überlegen, was du definiert hast!
kompletter C anfänger schrieb:>> Daraus folgt: der Fall, dass ein char (irgendeiner) in deinem String>> innerhalb des zulässigen Bereichs liegt, interessiert dich eigentlich>> nicht. Dich interessiert vielmehr, ob irgendeiner ausserhalb liegt. (...)>> mit anderen worten ich sollte einfach sagen,>
1
>if(char[i]<='9'){
2
>
Das ist zu wenig.
Denn wenn du dir eine ASCII Code Tabelle ansiehst, dann gibt es da
einige Zeichen, der Code eben kleiner als '9' ist.
Und genau genommen hab ich das nicht gesagt:
Ich hab dir gesagt: du kannst sofort bei einem Zeichen feststellen, ob
es ungültig ist. Aber du kannst nicht feststellen ob der String
insgesamt gültig ist, solange du nicht ALLE Zeichen untersucht hast.
Es gibt daher hier kein else.
Wenn das Zeichen ungültig ist, dann ist es ungültig und damit auch der
komplette String. Aber ob er gültig ist, kannst du erst feststellen,
wenn du durch die for-Schleife komplett durch bist und nie auf den Fall
'ungültiges Zeichen' gestossen bist.
Und 'char' ist sicherlich nicht der Name der Variable.
Und wo kommt jetzt auf einmal
1
20: int checknumbers (char* string[]) {
das * [] her?
du probierst durch Stochern im Nebel rum!
Das mag vielleicht bei Java gehen (obwohl ich auch das bezweifle), aber
in C funktioniert das ganz sicher nicht.
kompletter C anfänger schrieb:> return 1 machen?
Na ja.
Irgendwann musst du ja auch mal zu der Aussage "Der String ist in seiner
Gesamtheit gültig" kommen.
Bist du sicher, dass du schon mal Java oder sonst in irgendeiner
Programmiersprache programmiert hast?
Karl Heinz schrieb:> kompletter C anfänger schrieb:>>> return 1 machen?>> Na ja.> Irgendwann musst du ja auch mal zu der Aussage "Der String ist in seiner> Gesamtheit gültig" kommen.
Das ist simple Logik.
Wenn du Kisten mit Äpfel untersuchen sollst, ob die Kiste zum Kunden
raus darf, weil kein einziger Äpfel mit einer faulen Stelle in der Kiste
ist, dann
* untersuchst du Apfel für Apfel, in dem du sie rausnimmst und
untersuchst.
* wenn du auf einen fauligen stösst, dann kannst du die komplette Kiste
sofort verwerfen
* die Umkehrung kannst du aber erst dann feststellen, wenn du ALLE Äpfel
aus der Kiste rausgenommen hast. Erst dann, wenn du keinen einzigen
faulen Apfel entdeckt hast, steht fest, dass auch keiner in der Kiste
war und die Kiste darf zum Kunden rausgehen.
Alle Äpfel hast du aber erst dann untersucht, wenn du jeden einzelnen,
Stück für Stück aus der Kiste rausgenommen hast. Erst dann, wenn die
Kiste leer ist, steht fest, dass kein fauliger Apfel dabei war.
Ist wie in der Mathematik:
Ein Existenzbeweis ist oft recht einfach zu führen. Um eine Eigenschaft
X für eine All-Aussage zu beweisen, macht man oft die Umkehrung: man
zeigt, dass ein Objekt mit der gegenteiligen Eigenschaft nicht
existieren kann, bzw. wenn man die Existenz eines Objektes mit dieser
gegenteiligen Eigenschaft beweisen kann, dann ist damit die All-Aussage
gestorben.
Karl Heinz schrieb:> Bist du sicher, dass du schon mal Java oder sonst in irgendeiner> Programmiersprache programmiert hast?
ja aber sehr wenig Kenntnisse, deshalb fällt mir der ganze zusammen hier
schwer nach zu vollziehen. besonders die einzelnen fehler, die das
programm mir ausspuckt verstehe ich nicht.
wenn ich mir den code angucke:
1
intchecknumbers(char*string){
2
3
for(inti=0;i<=strlen(string);i++){
4
if(char[i]<='0'||char[i]>='9')
5
return-1;
6
}
7
return1;
8
}
verstehe ich den so,
die funktion läuft den char array durch, falls die eingegebenen zahlen
kleiner als null oder größer als 9 sind, spuckt er mir ne -1 aus
ansonsten eine 1
damit versuche ich dann
1
do{
2
putstring("Bitte 1. Zahl eingeben:\n");
3
getstring(string_1);
4
}while(checknumbers(string_1)>0)
5
zahl1=stringtoi(string_1);
fehlercode weiterhin hängt in der zeile 20 (for schleife)
> die funktion läuft den char array durch
dieser 'char' Array hat einen Namen! Variablen werden im Programmtext
angesprochen, indem man ihren Namen benutzt.
kompletter C anfänger schrieb:> verstehe ich den so,>> die funktion läuft den char array durch, falls die eingegebenen zahlen> kleiner als null oder größer als 9 sind, spuckt er mir ne -1 aus> ansonsten eine 1
Da steht nicht kleiner als und auch nicht größer als!
Und pack das int i aus der for-Schleife raus.
kompletter C anfänger schrieb:> fehlercode weiterhin hängt in der zeile 20 (for schleife)
Und auch weiterhin gilt der weiter oben schon angesprochene Rat:
Zieh halt die Definition vom i aus der for Schleife raus
1
intchecknumbers(char*string){
2
3
inti;
4
5
for(i=0;i<=strlen(string);i++){
6
....
Dein Lehrer hat hier
1
voidemain(void*arg)
2
{
3
longintzahl1;
4
longintzahl2;
5
longintergebnis;
6
charstring_1[100];
7
charstring_2[100];
8
9
....
ja auch nichts anderes gemacht.
Alle in der Funktion verwendeten Variablen sind fein säuberlich am
Anfang der Funktion aufgeführt.
Nicht das das jetzt alles wäre.
Da gibt es noch ein paar Punkte in deinem Programm.
Aber irgendwas musst du selbst auch machen.
Denn sonst kommt das Maischberger-Syndrom zum tragen, bei dem der
Nutzniesser zum Schluss fragen muss: Und was war da jetzt eigentlich
meine Leistung am ganzen?
Karl Heinz schrieb:> kompletter C anfänger schrieb:>>> wenn ich mir den code angucke:>>> int checknumbers (char* string) {>> ******* Wie heisst die Variable ?>>>>> for (int i = 0 ; i<=strlen(string);i++){>> if( char[i] <= '0' || char[i] >= '9' )>> **** ****> Welchen Namen benutzt du hier?>>> return -1;>> }>> return 1;>> }>>> die funktion läuft den char array durch>> dieser 'char' Array hat einen Namen! Variablen werden im Programmtext> angesprochen, indem man ihren Namen benutzt.
ich spreche sie doch an, sobald ich im hauptprogramm die methode aufrufe
mit
[c]
do {
putstring("Bitte 1. Zahl eingeben:\n");
getstring(string_1);
} while (checknumbers(string_1)>0)
zahl1 = stringtoi(string_1);
}
[c/]
Dirk B. schrieb:> kompletter C anfänger schrieb:>> den abschnitt verstehe ich soweit>> Sicher?> Ganz sicher mit den Grenzen des überprüften Bereichs?
jaein, warum sagen wir größer gleich bzw kleiner gleich den werten '0'
und '9' ? muss es nicht heißen kleiner als null (null muss ja mit
benutzt werden) und größer 9 (9 wird ja auch mitbenutzt)
danke erstmal für die hilfe, werde gerade gut vorgeführt und es setzt
ein minimales schamgefühl ein...
kompletter C anfänger schrieb:> warum sagen wir größer gleich bzw kleiner gleich den werten
Wir? Das kommt von dir.
> ich spreche sie doch an, sobald ich im hauptprogramm die methode aufrufe
mit
In deiner Funktion hat die Variable einen anderen Namen.
Und reservierte Wörte (dazu gehört auch char) nimmt man nicht für
Variablennamen.
kompletter C anfänger schrieb:> Karl Heinz schrieb:>> kompletter C anfänger schrieb:>>>>> wenn ich mir den code angucke:>>>> int checknumbers (char* string) {>>>> ******* Wie heisst die Variable ?>>>>>>>> for (int i = 0 ; i<=strlen(string);i++){>>> if( char[i] <= '0' || char[i] >= '9' )>>>> **** ****>> Welchen Namen benutzt du hier?>>>>> return -1;>>> }>>> return 1;>>> }>>>>> die funktion läuft den char array durch>>>> dieser 'char' Array hat einen Namen! Variablen werden im Programmtext>> angesprochen, indem man ihren Namen benutzt.>> ich spreche sie doch an, sobald ich im hauptprogramm die methode aufrufe
vom Hauptprogramm redet keiner.
Hier in dieser Funktion: Wie heisst die Variable in der der String
gespeichert ist (und genau deswegen sind Variablennamen wie 'String'
ziemlicher Unfug. Nenn sie meinetwegen "Text" oder "Prüftext" oder sonst
irgendwie, aber nicht mit einem Namen der einen feststehenden Begriff
umschreibt.
Ich hab dir die Wörter unterstrichen. So schwer kann das doch nicht
wirklich sein, an den 3 Stellen immer den gleichen Variablennamen zu
benutzen.
>> Sicher?>> Ganz sicher mit den Grenzen des überprüften Bereichs?>>> jaein, warum sagen wir größer gleich bzw kleiner gleich den werten '0'> und '9' ?
Weil du das so vorgegeben hast :-)
Teil des Lernprozesses ist es auch, Fehler zu machen, Fehler zu finden
und zu korrigieren.
kompletter C anfänger schrieb:> klappt soweit.>> danke für eure hilfe
da fehlt aber noch einiges
> Ansonsten soll eine geeignete> Fehlerausgabe mit Aufforderung einer erneuten Eingabe erfolgen.
wo ist die?
> strlen
ist immer noch drin, aber ist nicht der der Liste der erlaubten
Funktionen.
Peter II schrieb:>> strlen> ist immer noch drin, aber ist nicht der der Liste der erlaubten> Funktionen.
genau genommen ist auch die Verwendung von itostring bzw. stringtoi
nicht zulässig.
1
• Die zwei Dezimalzahlen sollen addiert und deren Summe in einer Integer-
2
Variablen (unsigned short int) gespeichert werden. Der Summenwert soll
3
dann mittels putstring() ausgegeben werden. Hierzu ist eine Umwandlung
4
der Integer-Variablen in einen entsprechenden String notwendig.
5
• Zur Lösung der Aufgabe dürfen ausschließlich die folgenden Funktionen
6
verwendet werden:
7
putstring(...)
8
getstring(...)
9
10
Andere schon bestehende Standardfunktionen, wie z.B. sprintf() oder scanf(), sind ausdrücklich verboten.
Speziell die Erwähnung, dass eine Umwandlung notwendig wäre (und die
Erwähnung von sprintf bzw. scanf, die man genau für diesen Zweck
einsetzen würde), lässt in mir den Gedanken aufkeimen, dass diese selbst
zu schreiben ist.
Auch stimmt der Datentyp der Ergebnisvariablen nicht. Gefordert ist ein
unsigned short int. Aktuell benutzt wird ein long int.
Speziell die Umwandlung von der Textform in die Zahlenform kann mit der
Gültigkeitsprüfung des Strings auf den erlaubten Zeichensatz ganz
einfach mitlaufen, wenn man bedenkt, dass an die Zahl 23 eine nächste
Stelle 7 'angehängt' wird, indem man rechnet 23 * 10 + 7, was 237
ergibt. In der Prüfroutine sind dazu alle notwendigen Informationen
vorhanden, so dass man die Vereinbarung des Returnwertes etwas abändern
könnte: liefert die Funktion eine negative Zahl (zb -1), dann war der
String ungültig. Andernfalls liefert sie genau die Zahl, die im String
in ihrer Textform dargestellt wurde.
Peter II schrieb:> da fehlt aber noch einiges>>> Ansonsten soll eine geeignete>> Fehlerausgabe mit Aufforderung einer erneuten Eingabe erfolgen.> wo ist die?
habe ich einfach in der methode realisiert:
[c]
int checklength (char* string) {
if (strlen(string)>4) {
putstring("Bitte erneute eingabe der Zahl: icht des
Zahlenbereiches:\n");
return -1;
}else{
return 1;
}
}
[c/]
Peter II schrieb:>> strlen> ist immer noch drin, aber ist nicht der der Liste der erlaubten> Funktionen.
wie müsste ich dann vorgehen?
[c]
int checknumbers (char* string) {
int i;
for (i = 0 ; i<string[i];i++) {
if (string[i] < '0' || string[i] > '9')
return -1;
}
return 1;
}
[c/]
?
kompletter C anfänger schrieb:> wie müsste ich dann vorgehen?
Indem du ausnutzt, dass in C jeder String mit dem Zeichen '\0' endet.
Deine Schleife bricht also nicht nach einer bestimmten Anzahl an
Wiederholungen ab, sondern genau dann wenn dieses Zeichen 'gesehen'
wird. Da du weiterhin Arrayschreibweise benutzt, würde es sich zb der
Einfachheit (für dich) anbieten, die for-Schleife gegen eine
while-Schleife zu ersetzen
Karl Heinz schrieb:> Deine Schleife bricht also nicht nach einer bestimmten Anzahl an> Wiederholungen ab, sondern genau dann wenn dieses Zeichen 'gesehen'> wird. Da du weiterhin Arrayschreibweise benutzt, würde es sich zb der> Einfachheit (für dich) anbieten, die for-Schleife gegen eine> while-Schleife zu ersetzen> ...>> i = 0;>> while( string[i] != '\0' ) {>> ....> i++;> }>> ....
kann ich dann nicht einfach
Kannst du. Gut erkannt.
Aber i.A. nimmt man for-Schleifen für eine vorher bestimmte Anzahl,
während bei while-Schleifen die Abbruchbedingung in der Schleife
bestimmt wird.
Man erkennt so beim lesen schon den Zweck.
Kannst Du. "for" und "while" unterscheiden sich (vereinfacht gesagt) für
Dich vorläufig nur darin, dass "for" halt zusätzlich die Initialisierung
und den Increment zum "while" zusätzlich liefert.
Anders gesagt,
1
int i;
2
for (i = 0; i < 10; i++)
3
{
4
....
5
}
tut das gleiche wie
1
int i;
2
i = 0;
3
while (i<10)
4
{
5
....
6
i++;
7
}
Statt "...." halt beliebigen Code einsetzen der da laufen soll. Aber das
am Rande.
Aber, blöde Frage, gehört zu den gültigen Zeichen bei Dezimalzahlen
nicht auch der Punkt? Oder halt das Komma?
Heinz L. schrieb:> Aber, blöde Frage, gehört zu den gültigen Zeichen bei Dezimalzahlen> nicht auch der Punkt? Oder halt das Komma?
Ist in der Aufgabenstellung nicht gefordert.
Und ich vermute mal: Aus gutem Grund. Denn dann wird die Umwandlung von
Text in Zahl aufwändiger
>putstring("Bitte erneute eingabe der Zahl: icht des
6
> Zahlenbereiches:\n");
7
>return-1;
8
>}
9
>return1;
10
>}
11
>
> funktioniert so nicht. die schleife wird immer wieder durchlaufen ohne> abbruchbedingung, selbst bei richtiger eingabe der zahlen.
wie war das nochmal mit den abhängigen Anweisungen zb von einem if und
dem möglicherweise notwendig werden von {-} Klammern?
Wenn du vernünftig einrücken würdest, dann würde dir vielleicht
auffallen, dass jetzt
1
intchecklength(char*string)
2
{
3
inti;
4
5
for(i=0;string[i]!='\0';i++)
6
{
7
if(i>3)
8
putstring("Bitte erneute eingabe der Zahl: icht des Zahlenbereiches:\n");
9
return-1;
10
}
11
12
return1;
13
}
plötzlich konzeptionell 2 Anweisungen vom Ausgang des if abhängen. Was
natürlich nicht geht, sondern die Klammerung der beiden Anweisungen zu
einem Block bedingt.
Dem Compiler ist deine Einrückung wurscht. Der liest so etwas immer so
1
intchecklength(char*string)
2
{
3
inti;
4
5
for(i=0;string[i]!='\0';i++)
6
{
7
if(i>3)
8
putstring("Bitte erneute eingabe der Zahl: icht des Zahlenbereiches:\n");
9
10
return-1;
11
}
12
13
return1;
14
}
Aber für dich als Programmierer ist es nicht wurscht. Denn dir erzählt
die Einrückung etwas und hilft dir dabei, solche Fehler zu finden.
Das heisst natürlich: Wenn man konsistent einrücken würde.
>> schreibe, ignoriert er die if anweisung komplett und nimmt nicht nur> zahlen bis max. 4 an> sondern auch 5-x stellige zahlen
Dann nimm dir ein Blatt Papier, schreib deine Variablen auf
1
i
2
+-------+
3
| |
4
+-------+
nimm einen Text an, zb "8765" und spiel mal Computer, der dein Programm
abarbeitet
> int checklength (char* string) {> int i;> for (i = 0;string[i]!='\0';i++){
erster Teil: Initialisierung. i auf 0 setzen
ALso schreibst du die 0 in das Feld rein, das du auf dem Papier mit 'i'
beschriftet hast.
1
i
2
+-------+
3
| 0 |
4
+-------+
Abbruchbedingung prüfen
1
string[i]!='\0'
String, das war "8765". Das Zeichen mit dem Index 0, das ist '8'. Ist
'8' ungleich '\0'? Ja, ist es. Also wird die Schleife ein weiteres mal
durchlaufen.
"Die Schleife", das ist der Teil von der öffnenden { bis zur zugehörigen
schliessenden }. Also der Teil hier
1
...............{
2
>if(i>3)
3
>{
4
>
5
>
6
>return-1;
7
>}else{
8
>return1;
9
>}
10
>}
Dann wollen wir mal. Was passiert innerhalb des Schleifendurchlaufs?
1
if(i>3)
ist i größer als 3? Schau auf deinen Zettel. i hat den Wert 0. Und 0 ist
nicht größer als 3. Also wird nicht der then-Zweig genommen, sondern der
else Zweig
1
}else{
2
return1;
Aha. wenn der else Zweig genommen wird, dann wird aus der Funktion
ausgestiegen und der zurückgelieferte Wert ist 1.
Ist es das was du wolltest?
Ist es wirklich so, dass wenn bereits das erste Zeichen ungleich '\0'
ist, die Länge damit automatisch gültig ist?
Du probierst einfach nur durch Stochern rum. Du schreibst einfach
irgendwas hin ohne dir die Logik dahinter zu überlegen, die dein
Geschreibsel ergibt. Das hat keinen Sinn.
Ich bin raus.
Und PS:
Die Sache mit der Einrückung .... das war ernst gemeint!
ich muss noch verstehen, wie ich die klammern zu setzten habe und das
richtige einrücken.
die unterschiedlichen schleifen bereiten mir noch probleme, bzw die
klammersetzung. wie die schleife durchlaufen wird bei unterschiedlichen
setzung der klammer bei einem array.
1
intchecknumbers(char*string){
2
inti;
3
for(i=0;string[i]!='\0';i++){
4
if(string[i]<'0'||string[i]>'9'){
5
putstring("Bitte erneute eingabe der Zahl: nicht im Zahlenbereich:\n");
6
return-1;
7
}
8
}
9
10
return1;
11
}
12
13
intchecklength(char*string){
14
inti;
15
for(i=0;string[i]!='\0';i++){
16
if(i>3){
17
putstring("Bitte erneute eingabe der Zahl: nicht im Zahlenbereich:\n");
18
return-1;
19
20
}
21
}
22
23
return1;
24
}
der code funktioniert so weit. werde weiter üben und danke für die
aufgebrachte zeit und geduld... :|
kompletter C anfänger schrieb:> ich muss noch verstehen, wie ich die klammern zu setzten habe und das> richtige einrücken.>> die unterschiedlichen schleifen bereiten mir noch probleme, bzw die> klammersetzung. wie die schleife durchlaufen wird bei unterschiedlichen> setzung der klammer bei einem array.
Nach einer if-Anweisung oder Schleife kommt eine Anweisung.
Du kannst mithilfe der {} mehrere Anweisungen zu einem Block
zusammenfasssen, der dann wieder als eine Anweiung gilt.
Und wegen Einrückung: http://de.wikipedia.org/wiki/Einr%C3%BCckungsstil
Du solltest Funktion von Ein-/Ausgabe trennen.
checknumbers prüft auf Ziffern und gibt einen entsprechenden Logikwert
zurück. 0 und 1 bieten sich da an.
Die Meldung an den Nutzer gibt die rufende funktion aus.
checklength sollte die Länge ermitteln (also mehr ein stringlen sein)
und die rufende Funktion prüft auf die richtige Länge.
Dirk B. schrieb:> checklength sollte die Länge ermitteln (also mehr ein stringlen sein)> und die rufende Funktion prüft auf die richtige Länge.
das finde ich noch ok, auch der Name passt zum Inhalt. Aber die
Fehlermeldung sollte in dieser Funktion ausgegeben werden.
Karl Heinz schrieb:> Heinz L. schrieb:>>> Aber, blöde Frage, gehört zu den gültigen Zeichen bei Dezimalzahlen>> nicht auch der Punkt? Oder halt das Komma?>> Ist in der Aufgabenstellung nicht gefordert.> Und ich vermute mal: Aus gutem Grund. Denn dann wird die Umwandlung von> Text in Zahl aufwändiger
Wie bestimmt sich dann bei der eingegebenen Zahl der Vor- und wie der
Nachkommabereich? Weil wenn da beispielsweise "9.5544" eingegeben wird
bricht die Zahlenprüf-Routine beim Punkt ab, weil das Zeichen ja nicht
"gültig" ist. Und einfach sagen dass die Eingabe ohne Dezimalpunkt/komma
zu erfolgen hat und die letzten 4 Stellen als Nachkommastellen nehmen
nehmen geht nicht, weil die Aufgabenstellung explizit von MAXIMAL 4
Dezimalstellen spricht, es können also auch weniger sein.
Ich hoffe wir verrennen uns hier nicht gerade darin das "nur" für
Integerzahlen zu lösen, weil wir dann ggf. noch einiges an Mehraufwand
vor uns haben!
Ich glaub nebenbei auch nicht dass die Verwendung von stringtoi und
itostring erlaubt ist, steht ja da dass:
Zur Lösung der Aufgabe dürfen ausschließlich die folgenden Funktionen
verwendet
werden:
putstring(...)
getstring(...)
Ausserdem wird's einfacher wenn man das selbst in der Schleife
durchführt. ;)
Heinz L. schrieb:> Ich hoffe wir verrennen uns hier nicht gerade darin das "nur" für> Integerzahlen zu lösen
Das ist ein Übungsbeispiel für Programmieranfänger!
Die haben Probleme mit vergessenen Strichpunkten, schwimmen bei
syntaktischen Problemen, haben algorithmische Mängel auf einfachstem
Niveau.
Derartige Feinheiten wie allgemeine Verwendbarkeit, sind zur Zeit nicht
wirklich relevant.
Hier geht es darum, erst mal krabbeln zu lernen! New York Marathon kommt
später. Vielleicht in 1 Jahr oder so.
Und wenn ich mir die 'Performance' des TO so ansehe, dann muss man schon
froh sein, wenn er zumindest die wesentlichsten Eckpunkte der
Aufgabenstellung im Sinne der Aufgabe lösen kann - eigenständig lösen
kann.
Nochmal: Dass das für Dezimalzahlen gelöst werden soll ist nicht mein
Anspruch, ich leite den aus dem Ursprungsposting und hier aus diesem
Satz ab:
Der Benutzer wird aufgefordert nacheinander zwei positive Dezimalzahlen
(mit jeweils
maximal 4 Dezimalstellen) einzugeben. Die Eingabe der Dezimalzahlen
erfolgt unter
Verwendung der Funktion getstring() und liefert somit zwei Strings.
Heinz L. schrieb:> Nochmal: Dass das für Dezimalzahlen gelöst werden soll ist nicht mein> Anspruch, ich leite den aus dem Ursprungsposting und hier aus diesem> Satz ab:
Dann sieh dir das Vorgabebeispiel seines Betreuers an.
Alles ganze Zahlen.
Auch Dezimalzahlen können einfach nur ganze Zahlen sein.
Ausserdem wäre es ein wenig sinnlos, Dezimalzahlen mit Nachkommaanteil
eingeben zu können und dann für die Summenvariable einen unsigned short
zu verlangen.
Du liest ein bisschen zu viel aus dem Begriff "Dezimalzahl" heraus.
Hier geht es nicht um das Ziel. Hier ist der Weg das Ziel.
Die Zielsetzung der Aufgabenstellung besteht nicht darin, ein
super-duper Programm zu kriegen. Die Zielsetzung besteht darin, dem
Lernenden Übung zu verschaffen. Und das angepasst an sein Können und
momentanes Leistungsniveau. Jeder Ausbildner weiss, dass es ziemlich
schwer ist, halbwegs interessante Aufgabenstellungen zu finden, die mit
dem begrenzten Wissenschatz und dem Können von Anfängern von diesen noch
lösbar sind.
Ist alles richtig, ich will nur nicht dass der TE dann am Ende nach
Stunden und Tagen vor seinem Betreuer sitzt und der das Ding mit einem
Hinweis auf "aber das ist nicht Dezimalusw" verwirft.
Warum reitet der sonst so auf den "bis zu 4 Nachkommastellen" rum wenn's
dann am Ende eh wieder egal ist? Ich glaub eher dass der sich die Lösung
als etwas mit dem "aus Fixkomma mach Integer durch *10000" Schmäh denkt.
Insgesamt geb ich Dir ja recht, die Aufgabenstellung ist nicht eindeutig
(weil 2 Zeilen weiter unten steht "Diese beiden Strings sollen
dahingehend überprüft werden ob diese [...] ausschließlich die
ASCII-Zeichen 0 bis 9 beinhalten." was prinzipiell Dezimaltrennzeichen
ausschließen würde). Blöderweise, und das Problem kenn ich noch zu gut
aus meiner Studienzeit, liegt die Auslegungshoheit für den Murks leider
bei dem, der ihn verbockt hat.
Entsprechend wär hier vielleicht Input vom Threadersteller hilfreich wie
er seinen Aufgabensteller einschätzt bzw. kann er diesen ja fragen was
denn nun Trumpf ist.
Heinz L. schrieb:> Warum reitet der sonst so auf den "bis zu 4 Nachkommastellen" rum
wo liest du was von Nachkommastellen?
Da steht Dezimalstellen!
Und die stehen dort, damit er erstens die Strings auf Maximum
dimensionieren kann und damit er keine Probleme beim Rechnen kriegt,
wenn jemand meint er müsse dem Programm 872345612309724367234 +
621734768732648961847 als Rechenaufgabe geben.
Und unsigned short ist ja auch begrenzt.
Da passen alle positiven vierstelligen Zahlen rein.
Und die Summe zweier solcher Zahlen auch noch.
Als ob sich jemand dabei was gedacht hat.