Blutiger Neuprogrammierer braucht dringendst Hilfe (String to Integer)
-
Man_Tis schrieb:
Du benutzt auch pointer, im umgang damit bin ich nicht gut vertraut, wie gesagt ich fange erts an mich an c zu "gewöhnen".
Der Pointer war die elegante Möglichkeit, mit dem Vorzeichen umzugehen (gehört das überhaupt zur Aufgabe?). So würde das mit Index aussehen:
int stoi (char s[]) { int result; int sign; int i; char c; int s_index; if (s[0] == '-') { sign = -1; s_index = 1; } else { sign = 1; s_index = 0; } result = 0; while (s[s_index]) { c = s[s_index]; i = ctoi(c); if (i < 0) { printf ("Sie haben einen falschen Wert eingegeben\n"); return 0; } result *= 10; result += i; ++s_index; } return sign * result; }
viele grüße
ralph
-
WOW Danke spagetti und ralph, ihr seid super! So klappts bestimmt. Das Vorzeichen muss nur sozasagen erkannt werden um auch beim zweiten Teil der Aufgabe Hexa und Octa in negative Zahlen umzuwandeln.
Ihr seid echt Hilfsbereit!
-
Ich bin zufällig auf diese interessanten Lösungen gekommen und frage mich:
1. Fehlerhafte Eingabe mit mehreren Minuszeichen (oder Plus und Minus gemischt) in der Zahl.
2. + muss eigentlich auch erlaubt sein.
3. Wieso 16 Stellen? Wohl dem der einen 32-bit-Rechner hat, dann gehen kaum 10 Stellen, ein 64-bit-Rechner kann fast 20 Ziffern in int unterbringen. Eigentlich sollte das Programm doch den Überlauf selbst erkenntenDa es mein erster Beitrag in diesem Forum ist, bitte ich um Nachsicht, wenn ich die Gebrauchsanweisung noch nicht gelesen habe. Hier eine reine C-Lösung aus dem Visual Studio:
- reine Pointer-Lösung
- ctoi ist eigentlich überflüssig und testet unnötigerweise das Vorzeichen jedes Mal
- stattdessen einfach das vorder Nippel (Halbbyte) ausblenden, so ergibt sich der numerische Wert direkt ohne Subtraktion (ist auch viel schneller)[code="c"]
/*A031S_ZeichenInZahl_Minus.c : Einstiegspunkt der Konsolenanwendung*/
/*Parser: Liest Zeichenkette mit Ziffern ein und erzeugt eine Ganzzahl mit Vorzeichen und Pruefung*/#include <stdio.h>
#include <stdlib.h> /*fuer system*/#ifdef __cplusplus
#define KOMPILIERMODUS "mit C++"
#else
#define KOMPILIERMODUS "mit C"
#endif
#pragma message(KOMPILIERMODUS)int main(void) {
unsigned char cZahl[80+1]; /*Zeichenkette fester Laenge*/
unsigned char *cZeiger; /*Zeiger auf die Zeichenkette*/
long nErgebnis=0; /*Ergebnis*/
long nVorzeichen=1;
fprintf_s(stdout,"Zahl wird als Zeichenkette eingelesen: ");
fscanf_s(stdin,"%80s",cZahl,sizeof(cZahl)-1);
fprintf_s(stdout,"Sie haben eingegeben: %s\n",cZahl);
cZeiger=cZahl;
switch (cZeiger) {
case '-': nVorzeichen=-1; /*interessanter Fall ohne break*/
case '+': cZeiger++;break;
} /*switch*/
while (*cZeiger!='\0') { /*Zeigertechnik/
if (*cZeiger<'0'||*cZeiger>'9') {
fprintf_s(stderr,"Falsche Eingabe\n");
return -1;
} /*if*/
nErgebnis=nErgebnis*10+((*cZeiger)&0xF); /*Horner-Schema und numerischer Wert statt Zeichen*/
if (nErgebnis<0) {
fprintf_s(stderr,"Zahlenueberlauf\n");
return -2;
} /*if*/
cZeiger++;
} /*while*/
nErgebnis*=nVorzeichen;
fprintf_s(stdout,"Der numerische Wert ist %d\n",nErgebnis);
system("Pause");
return 0;
} /*main*/
-
Gut, ich lerne dazu, hier also der Quelltext noch einmal. Das Herzstück ist die Zeile 32.
/*A031S_ZeichenInZahl_Minus.c : Einstiegspunkt der Konsolenanwendung*/ /*Parser: Liest Zeichenkette mit Ziffern ein und erzeugt eine Ganzzahl mit Vorzeichen und Pruefung*/ #include <stdio.h> #include <stdlib.h> /*fuer system*/ #ifdef __cplusplus #define KOMPILIERMODUS "mit C++" #else #define KOMPILIERMODUS "mit C" #endif #pragma message(KOMPILIERMODUS) int main(void) { unsigned char cZahl[80+1]; /*Zeichenkette fester Laenge*/ unsigned char *cZeiger; /*Zeiger auf die Zeichenkette*/ long nErgebnis=0; /*Ergebnis*/ long nVorzeichen=1; fprintf_s(stdout,"Zahl wird als Zeichenkette eingelesen: "); fscanf_s(stdin,"%80s",cZahl,sizeof(cZahl)-1); fprintf_s(stdout,"Sie haben eingegeben: %s\n",cZahl); cZeiger=cZahl; switch (*cZeiger) { case '-': nVorzeichen=-1; /*interessanter Fall ohne break*/ case '+': cZeiger++;break; } /*switch*/ while (*cZeiger!='\0') { /*Zeigertechnik*/ if (*cZeiger<'0'||*cZeiger>'9') { fprintf_s(stderr,"Falsche Eingabe\n"); return -1; } /*if*/ nErgebnis=nErgebnis*10+((*cZeiger)&0xF); /*Horner-Schema und numerischer Wert statt Zeichen*/ if (nErgebnis<0) { fprintf_s(stderr,"Zahlenueberlauf\n"); return -2; } /*if*/ cZeiger++; } /*while*/ nErgebnis*=nVorzeichen; fprintf_s(stdout,"Der numerische Wert ist %d\n",nErgebnis); system("Pause"); return 0; } /*main*/
-
Ich kann deine Lösung zwar nicht beurteilen Waldschrat aber sie ist sicherlich sehr gut. Auch dir danke.
Ausser stdio dürfen wir nur selbstgeschriebene Funktionen benutzten denke ich.
-
Durchgeknallte C-Programmierer multiplizieren natürlich nicht mit +1 oder -1, sondern bilden das Zweierkomplement persönlich
/*nErgebnis*=nVorzeichen;*/ if (nVorzeichen<0) { nErgebnis=~nErgebnis+1; } /*if*/
stdlib.h ist nur für die Pause im Debug-Modus, sonst hält die Konsole nicht an.
Einfach weglassen und die vorletzte Zeile löschen.
Die Präprozessor-Anweisungen am Anfang dienen auch nur dazu, Dir zu zeigen, ob Du mit C oder C++ übersetzt. Können also auch entfallen.
-
Man_Tis schrieb:
Ich kann deine Lösung zwar nicht beurteilen Waldschrat aber sie ist sicherlich sehr gut.
Was denn nun? Du kannst sie nicht beurteilen und beurteilst sie dann doch?
Die Waldschrat"lösungen" sind Schrott und fehlerhaft und für einen Anfänger schädlich weil irreführend.
-
Dann korrigiere ich mich:
Herr Waldschrat ich habe keine Ahnung ob die Lösung das Problem überhaupt löst.Ich bin aufgrund der für einen Anfänger gefühlt hohen komplexität davon ausgegangen dass es "sicherlich" eine sehr gute Lösung ist.
-
Lieber Herr Man_Tis kopieren Sie den Quelltext einfach heraus und probieren Sie ihn aus. Hier ein Bildschirmausdruck:
Zahl wird als Zeichenkette eingelesen: -32767 Sie haben eingegeben: -32767 Der numerische Wert ist -32767 Drücken Sie eine beliebige Taste . . .
Ja, so schnell geht es. Alles Schrott und fehlerhaft, aber Herr Wutz: Wo sind die Fehler?
Die schlechte Nachricht
Richtig, das Programm hat einen Fehler und Herr Wutz haben ihn entdeckt.Die gute Nachricht:
Der Prüfer wird diesen Fehler wahrscheinlich nicht finden.Hier die Erklärung:
Das Programm ist dazu ausgelegt, jeden Ganzzahltyp aus einer Zeichenkette zu erzeugen oder einen Fehler zu melden. Dazu kann man in der Zeile 17 den Datentyp von char, short, long, int, long long, Int32, Int64 und was der Kompiler sonst noch versteht ändern.
int sollte als prozessorabhängiger Datentyp eigentlich verboten werden.
Ich versuche den Fehler an short zu erklären:
Der Zahlenbereich von short ist -32768 ... 32767
Wir sehen sofort, dass die Anzahl der Zeichen (Vorzeichen und Ziffern) nicht dazu dienen kann, einen Zahlenüberlauf zu erkennen.Leider ist aber der Zahlenbereich unsymmetrisch. Wenn wir also wie im Programm (und bei allen anderen Lösungen) zuerst das Vorzeichen entfernen, um dann den Ganzzahlanteil umzuwandeln, dann läuft dieser bei +32768 leider über, d. h. dieser Wert wird vom aktuellen Programm als fehlerhafte Eingabe interpretiert. Er wird -32768, was also wünschenswert ist. Dann muss aber die anschließende Negation verhindert werden.
Vielleicht noch ein Wort zu einzelnen Anweisungen
unsigned char cZahl[80+1]; /*Zeichenkette fester Laenge*/
Dies ist der Puffer für eine vollständige Zeile der Konsole, die 80 Schreibstellen besitzt.
unsigned
ist zwar logisch richtig, da der ASCII nur positive Zahlen kennt, kann aber entfallen.
fprintf_s. fscanf_s
sind sichere Ein-/Ausgabefunktionen, bei denen der Ein-/Ausgabestrom umschaltbar ist. Daher werden die Fehlermeldungen auf stderr ausgegeben.
Die zentrale Anweisung ist
(*cZeiger)&0xF
Unsere Altvorderen haben den ASCII durchaus sinnvoll festgelegt
`'3' binär 0011 0011
3 binär 0000 0011`
Um aus einer Ziffer '3' eine Zahl 3 zu machen, muss nur das vordere Halbbyte gelöscht werden. Dies geschieht durch eine bitweisen Und-Verknüpfung mit der Maske 0000 1111
Das geht schneller als
Ziffer - '0'
oderZiffer - 48
oderZiffer - 0x30
, was in allen Lehrbüchern und Manuskripten programmiert wird.Ein Prozessor subtrahiert nicht. Vielmehr geschieht folgendes:
48 ins Zweierkomplement transformieren, also
bitweise invertieren
1 addieren
das Ergebnis zur aktuellen Ziffer hinzuaddieren, was dann der Subtraktion entspricht.Somit ist (wahrscheinlich aus der Aufgabenstellung heraus) der Einsatz einer Funktion ctoi überflüssig. Ich versuche einmal die Gebrauchsanweisung dazu zu schreiben;
ctoi wandelt eine einzelne Ziffer in eine Ganzzahl um.
Ist das Ergebnis -1, dann ist ein Minuszeichen erkannt.
fehlt: Ist das Ergebnis -2, dann ist ein Pluszeichen erkannt.
Ist das Ergebnis -3, dann handelt es sich um keine Ziffer.Jetzt muss also das rufende Programm alle diese Fälle aussortieren
summand=ctoi(str[stelle]); if (ctoi(str[stelle]) == -1) { negation =-1; summand=0; } else if (ctoi(str[stelle])== -2||(ctoi(str[stelle])==-1&&stelle<0)) { printf("Sie haben einen falschen Wert eingegeben"); return 0; }
Übrigens: Wieso kann in diesem Programm stelle negativ werden?
Verehrter Herr Wutz
Eine herzliche Bitte, definieren Sie "Schrott" und sagen Sie mir, wo die Fehler sind.Sie haben natürlich mit dem Schrott für "blutigen Anfänger" recht, aber der sollte das eigentlich nach dieser meiner Überschrift das Programm gar nicht lesen.
Hierzu eine kleine Nebenbemerkung;
Ich halte ein Programm (Pointer-Version) für "Schrott", das in stoi die Funktion ctoi nicht weniger als dreimal aufruft, das erlaubte +-Zeichen ignoriert und nicht bis an den Rand des Wertebereichs getestet wird.
-
Nachdem die Wutz (südhessischer Ausdruck) nicht mehr durch den Wald saut, traut sich auch ein Waldschrat wieder aus seinem Loch.
Da in der Anfrage die Aufgabenstellung fehlt, scheint aber der Einsatz von Unterprogrammen eines der didaktischen Ziele der Praktikums gewesen zu sein. Hier also ein Lösungsvorschlag mit ctoi und stoi. Natürlich bleibt die Frage offen; "Darf eine Aufgabenstellung für Anfänger und damit ein Programm aus didaktischen Gründen fehlerhaft sein oder nicht?" Ein Waldschrat meint "Nein".
In der Aufgabenstellung scheint die Anweisung zu exitieren, in ctoi die Werte -1 bzw. -2 zurückzugeben, um das negative Vorzeichen bzw. einen Fehler zu melden. Genau genommen handelt es sich um zwei für den Datentyp char verbotene Werte.
Hier fängt das Problem mit stoi an. Es gibt keine verbotenen int-Zahlen. Damit kann ein Fehler nicht an das rufende Programm gemeldet werden. Haarspalterisch muss ich nun sagen: "Die Aufgabenstellung ist für den praktischen Einsatz falsch. stoi muss noch einen weiteren Parameter besitzen. Profis wissen, dass beispielsweise scanf zwei Werte zurückgibt." Das ist für Herrn Man_tis nicht wirklich zielführend. Andere meinen sogar, dass solche Gedanken "Schrott" sind.
Ich habe das Programm "entschrottet", um ganz blutige Anfänger nicht zu sehr zu erschrecken. Wenn auch limits.h verboten sein sollte, kann man entweder ein
#define INT_MIN -2147483648
einsetzen oder sich ganz gehörig beim Dozenten beschweren.
/*A031S_ZeichenInZahl_Up.c : Einstiegspunkt der Konsolenanwendung*/ /*Parser: Liest Zeichenkette mit Ziffern ein und erzeugt eine Ganzzahl (Unterprogrammtechnik)*/ #include <stdio.h> #include <limits.h> int ctoi(char c) { /*gibt numerischen Wert einer Ziffer zurueck*/ return c<<0xF; } /*ctoi*/ int stoi(unsigned char *cZahl) { /*gibt den numerischen Wert einer Zeichenkette zurueck*/ /*Problem: Es gibt in dieser Form keine Moeglichkeit, einen Fehler an das rufende Programm zu senden*/ unsigned char *cZeiger; /*Zeiger auf die Zeichenkette*/ int nErgebnis=0; /*Ergebnis*/ int nVorzeichen=1; cZeiger=cZahl; switch (*cZeiger) { case '-': nVorzeichen=-1; /*interessanter Fall ohne break*/ case '+': cZeiger++;break; } /*switch*/ while (*cZeiger!='\0') { /*Zeigertechnik*/ if (*cZeiger<'0'||*cZeiger>'9') { fprintf_s(stderr,"Falsche Eingabe\n"); fprintf_s(stderr,"Was soll ich nur tun? Ich mache einfach weiter, da exit zu brutal ist.\n"); } /*if*/ nErgebnis=nErgebnis*10+((*cZeiger)&0xF); /*Horner-Schema und numerischer Wert statt Zeichen*/ if (nErgebnis<0 && (nVorzeichen==1 || nErgebnis!=INT_MIN)) { fprintf_s(stderr,"Zahlenueberlauf\n"); fprintf_s(stderr,"Was soll ich nur tun? Ich mache einfach weiter, da exit zu brutal ist.\n"); } /*if*/ cZeiger++; } /*while*/ if (nVorzeichen<0 && nErgebnis!=INT_MIN) { /*nErgebnis*=nVorzeichen;*/ nErgebnis=~nErgebnis+1; } /*if*/ return nErgebnis; } /*stoi*/ int main(void) { unsigned char cZahl[80+1]; /*Zeichenkette fester Laenge*/ fprintf_s(stdout,"Zahl wird als Zeichenkette eingelesen: "); fscanf_s(stdin,"%80s",cZahl,sizeof(cZahl)-1); fprintf_s(stdout,"Sie haben eingegeben: %s\n",cZahl); fprintf_s(stdout,"Der numerische Wert ist %d\n",stoi(cZahl)); return 0; } /*main*/
Hier noch meine Testfälle. Ich hoffe, dass damit keine Fehler mehr in der Lösung existieren. Wie jeder sieht, liefert stoi bei Zahlenüberläufen falsche Werte an das Hauptprogramm zurück. Die nächste Aufgabenstellung im Praktikum sollte daher diese Fälle zum Thema haben.
Zahl wird als Zeichenkette eingelesen: 2147483647 Sie haben eingegeben: 2147483647 Der numerische Wert ist 2147483647 Drücken Sie eine beliebige Taste . . . Zahl wird als Zeichenkette eingelesen: -2147483647 Sie haben eingegeben: -2147483647 Der numerische Wert ist -2147483647 Drücken Sie eine beliebige Taste . . . Zahl wird als Zeichenkette eingelesen: 2147483648 Sie haben eingegeben: 2147483648 Zahlenueberlauf Was soll ich nur tun? Ich mache einfach weiter, da exit zu brutal ist. Der numerische Wert ist -2147483648 Drücken Sie eine beliebige Taste . . . Zahl wird als Zeichenkette eingelesen: -2147483648 Sie haben eingegeben: -2147483648 Der numerische Wert ist -2147483648 Drücken Sie eine beliebige Taste . . . Zahl wird als Zeichenkette eingelesen: 2147483649 Sie haben eingegeben: 2147483649 Zahlenueberlauf Was soll ich nur tun? Ich mache einfach weiter, da exit zu brutal ist. Der numerische Wert ist -2147483647 Drücken Sie eine beliebige Taste . . . Zahl wird als Zeichenkette eingelesen: -2147483649 Sie haben eingegeben: -2147483649 Zahlenueberlauf Was soll ich nur tun? Ich mache einfach weiter, da exit zu brutal ist. Der numerische Wert ist 2147483647 Drücken Sie eine beliebige Taste . . .
Der Waldschrat verkriecht sich wieder in seine Höhle und hält vorsichthalber seinen Winterschlaf, denn bisher hat ihm noch niemand gesagt, dass seine Programme "Schrott" sind (ok, Fehler hat er immer schon mal gemacht).
-
Uhhh, jetzt bin ich noch einmal schweißgebadet in meiner Kuschelhöhle aufgewacht.
Ich schäme mich für die Fehler bei der Umstellung auf Funktionen.
Ich schäme mich etwas weniger, da sich die Fehler gegenseitig aufheben.
Eigentlich muss ich mich nicht schämen, da keiner bis hier gelangt.
Böse Zungen behaupten, dass ich das mit Absicht eingebaut habe, um noch eine Meldung zu schreiben.Leider ist der Operator in der Funktion falsch umkopiert worden. Richtig ist
int ctoi(char c) { /*gibt numerischen Wert einer Ziffer zurueck*/ return c&0xF; } /*ctoi*/
Man sieht eigentlich sehr schön, dass diese Funktion total überflüssig ist.
Da die Funktion nicht aufgerufen wird, hatte der Fehler keine Wirkung. Also muss Zeile 32 geändert werden in
nErgebnis=nErgebnis*10+ctoi(*cZeiger); /*Horner-Schema und numerischer Wert statt Zeichen*/
Nun hat Herr Man_tis noch das Ausgabeproblem. Zuerst die einfache Lösung zur Ausgabe in oktal und sedezimal (hexadezimal ist englischer Mischmasch: hexa griechisch, dezimal lateinisch)
int main(void) { unsigned char cZahl[80+1]; /*Zeichenkette fester Laenge*/ int nZahl; fprintf_s(stdout,"Zahl wird als Zeichenkette eingelesen: "); fscanf_s(stdin,"%80s",cZahl,sizeof(cZahl)-1); fprintf_s(stdout,"Sie haben eingegeben: %s\n",cZahl); nZahl=stoi(cZahl); fprintf_s(stdout,"Der numerische Wert ist %d oktal: %o sedezimal: %X\n",nZahl,nZahl,nZahl); return 0; } /*main*/
Da
cout
letztendlich intern dieselben Funktionen wieprintf
benutzt, kann man auch dort mit den Ausgabemanipulatorencout<<dec, cout<<oct, cout<<hex
die automatische Umwandlung in C++ erzeugen.
Das Ergebnis sieht dann am Zahlenüberlauf von C folgendermaßen aus:Zahl wird als Zeichenkette eingelesen: 2147483647 Sie haben eingegeben: 2147483647 Der numerische Wert ist 2147483647 oktal: 17777777777 sedezimal: 7FFFFFFF Drücken Sie eine beliebige Taste . . . Zahl wird als Zeichenkette eingelesen: -2147483648 Sie haben eingegeben: -2147483648 Der numerische Wert ist -2147483648 oktal: 20000000000 sedezimal: 80000000 Drücken Sie eine beliebige Taste . . .
Wenn der Dozent die Benutzung der automatischen Formatierung nicht so gerne sieht oder seine schwarze Seele auf die Idee kommt, die Zahlen im Fünfer- oder Zwölfersystem anzeigen zu lassen, hilft nur noch ein Basiswandler
/*A031C_Basiswandler.cpp: Einstiegspunkt der Konsolenanwendung.*/ /*Einfacher Basiswandler fuer Ganzzahlen*/ #include <stdio.h> #include <stdlib.h> /*fuer system*/ #include <string.h> /*fuer _strrev*/ #ifdef __cplusplus #pragma message("mit C++") #else #pragma message("mit C") #endif void wandleIterativ(unsigned long nD,unsigned long nBasis) { char cErgebnis[80+1]; /*_strset(cErgebnis,NULL); /*Angstanweisung*/ unsigned char cZ,nI=0; while (nD>0) { /*Iteration*/ cZ=(unsigned char)((nD%nBasis)+48); /*Ziffer*/ if (cZ>57) cZ+=7; /*Buchstabe*/ nD/=nBasis; cErgebnis[nI++]=cZ; /*hinten anhängen*/ } /*while*/ cErgebnis[nI]='\0'; fprintf_s(stdout,"\nErgebnis zur Basis %lu: %s\n\n",nBasis,_strrev(cErgebnis)); } /*wandleIterativ*/ void wandleRekursiv(unsigned long nD,unsigned long nBasis) { unsigned char cZ; if (nD!=0) { cZ=(unsigned char)((nD%nBasis)+48); /*Ziffer*/ if (cZ>57) cZ+=7; /*Buchstabe*/ fprintf_s(stdout,"%c",cZ); wandleRekursiv(nD/nBasis,nBasis); } /*if*/ } /*wandleRekursiv*/ int main() { unsigned long nD,nBasis; fprintf_s(stdout,"Dezimale Ganzzahl: ");scanf_s("%ul",&nD); do { fprintf_s(stdout,"Zielbasis 2-36: ");fscanf_s(stdin,"%ul",&nBasis); } while (nBasis<2||nBasis>36); wandleIterativ(nD,nBasis); /*Reihenfolge wird intern korrigiert*/ fprintf_s(stdout,"Rekursions-Ergebnis in umgekehrter Reihenfolge: "); wandleRekursiv(nD,nBasis); /*Rekursion erzeugt die Ziffern in umgekehrter Reihenfolge*/ fprintf_s(stdout,"\n\n"); system("Pause"); return 0; } /*main*/
Der Variationsbereich der Basen ist von 2 bis 36 (10 Ziffern plus 26 Buchstaben). Wer mehr will, muss mit Sonderzeichen in der Ausgabe rechnen.
Noch einmal zurück zur eher bescheidenen Aufgabenstellung. Sie muss richtig lauten:
Schreiben Sie eine Funktion
int stoi(const char *cZahl, int *nZahl)
die eine Zeichenkette
cZahl
in eine numerische GanzzahlnZahl
umwandelt.
Der Rückgabewert ist-1
, wenn kein Fehler aufgetreten ist. Falls ein Fehler auftritt, gibt der Rückgabewert (>=0) die Position des ersten fehlerhaften Zeichens an.nZahl
enthält dann den Wert des als Zahl erkannten Kopfes.Herr Man_tis wird folgende Probleme haben:
1. Im ersten Semester hört man nichts über
const
, also einfach weglassen.
2. Die Parameterübergabe per Referenz kommt im Unterricht wohl noch. Also muss er die Lösung bis auf die Weihnachtsferien verschiebenOhne die Forderung nach der Ausgabe der Fehlerstelle erreichen wir das Ergebnis im aktuellen Programm durch einen Aussprung
if (*cZeiger<'0'||*cZeiger>'9') { fprintf_s(stderr,"Falsche Eingabe\n"); fprintf_s(stderr,"Ich ende ganz einfach.\n"); return nErgebnis; } /*if*/
Eine Alternative besteht darin, alle fehlerhaften Zeichen auszulassen
while (*cZeiger!='\0') { /*Zeigertechnik*/ if (*cZeiger<'0'||*cZeiger>'9') { fprintf_s(stderr,"Falsche Eingabe\n"); fprintf_s(stderr,"Ich lasse das Zeichen einfach weg.\n"); } else { nErgebnis=nErgebnis*10+ctoi(*cZeiger); /*Horner-Schema und numerischer Wert statt Zeichen*/ } /*if*/
Ürigens, durch die Ausgabe auf den Fehlerstrom
stderr
kann das eigentliche Ergebnis ohne Meldungen aus dem Ausgabestromstdout
abgeholt werden.Der Zahlenüberlauf ist ein "ernster Fehler" (severe error), der so nicht repariert werden kann. Das Ergebnis einfach auf 0 zu setzen ist mehr als fragwürdig, da 0 natürlich auch als normale Zahl existiert.
Noch ein Tipp für Neugierige:
Schauen Sie doch einfach einmal in
limits.h
hinein. Sie finden#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */
Warum nicht -2147483648 ?? Sieht wie eine "Angsanweisung" aus, falls der Kompiler nur -2147483647