atoi Fehlerprüfung
-
Hi!
Gibt es eine Möglichkeit, den Rückgabewert o.ä. von atoi auf Fehler zu prüfen?
Ich meine keine Fehler wie NULL-Zeiger oder Ganzzahlüberläufe, sondern "Formatfehler". Es wird nämlich 0 zurückgegeben, wenn die Zeichenkette nicht umgewandelt werden konnte, allerdings ist 0 auch eine gültige Zahl.
-
Du kannst dafür errno abfragen.
-
David_pb schrieb:
Du kannst dafür errno abfragen.
Dachte ich auch, aber 1. steht in der Doku nichts davon, und zweitens ist errno "immer" 0.
-
Du könntest auch eine C++-Methode zur Umwandlung benutzen. Ein stringstream beispielsweise bietet auch Feedback im Fehlerfall.
-
SeppJ schrieb:
Du könntest auch eine C++-Methode zur Umwandlung benutzen. Ein stringstream beispielsweise bietet auch Feedback im Fehlerfall.
Da ist was dran, allerdings ist es nur eine kleine Umwandlung wo ich nicht unbedingt ein Objekt konstruieren wollte.
Btw: Wäre das fail-Bit denn dann gesetzt oder wie müsste ich prüfen?
-
De-Be schrieb:
Da ist was dran, allerdings ist es nur eine kleine Umwandlung wo ich nicht unbedingt ein Objekt konstruieren wollte.
Und? Wenn es nicht superzeitkritisch ist, dann ist ein stringstream doch ok.
Btw: Wäre das fail-Bit denn dann gesetzt oder wie müsste ich prüfen?
Jupp. Oder einfach
if (stream_objekt >> int_variable) /* ok*/ else /*nicht ok*/. Oder es gibt auch noch die Möglichkeit den Stream so einzustellen, dass er bei Nicht-Gelingen eine Exception wirft.
-
Du kannst dir ja selber was "zusammenhacken"
int GetDigit(char d, int base) { switch(d) { case '0':return 0; case '1':return 1; case '2':return (base>2)?2:-1; case '3':return (base>3)?3:-1; case '4':return (base>4)?4:-1; case '5':return (base>5)?5:-1; case '6':return (base>6)?6:-1; case '7':return (base>7)?7:-1; case '8':return (base>8)?8:-1; case '9':return (base>9)?9:-1; case 'A': case 'a': return (base>10)?10:-1; case 'B': case 'b': return (base>11)?11:-1; case 'C': case 'c': return (base>12)?12:-1; case 'D': case 'd': return (base>13)?13:-1; case 'E': case 'e': return (base>14)?14:-1; case 'F': case 'f': return (base>15)?15:-1; } return -1; } template<typename Type> bool StringToInt(const std::string& s, Type* t, int base=10) { Type k=1; int i; if(s.length()==0) return false; *t=0; for (i=(s.length()-1);i>=0;i--) { int d=GetDigit(s[i],base); if(d==-1) { if((s[i]=='-' && i==0) // okay- Vorzeichen || (base==16 && s[i]=='x')) // oder 'x', wenn base 16 ist { if(s[i]=='-') (*t)*=(-1); return true; } *t=0; return false; } *t+= d*k; k*=base; } return true; }Bei einem Aufruf kannst du immer den Returnwert testen. Von solch einem Code kann ich selber aber nur abraten, ich habe das vor JAHREN einmal geschrieben, voll getestet ist es nicht.
-
Die C++-Lösung ist wohl am besten. Danke.