atoi() Frage
-
Zum Probieren ob atoi funktioniert hab ich folgendes geschrieben:
#include <iostream> #include <string> #include <stdio.h> #include <stdlib.h> using namespace std; int main () { string text; cin>>text; int Zahl; Zahl=atoi(text.c_str); cout<<Zahl; }
Nun gibt er mir so einen Schwachsinn von wegen:
13 argument of type `const char*(std::basic_string<char, std::char_traits<char>, std::allocator<char> >::)() const' does not match `const char*'
Hat schon davor nicht funktioniert als ich bei atoi(text.c_str) das .c_str weggelassen habe aber scheinbar hatten viele das Problem;)
MfG
-
c_str ist eine Memberfunktion, du hast die Klammern vergessen.
Aber es gibt auch einfachere Methoden um in C++ Strings in Integer umzuwandeln, als atoi. In den FAQ müssten mehrere Methoden beschrieben sein.
-
SeppJ schrieb:
Aber es gibt auch einfachere Methoden um in C++ Strings in Integer umzuwandeln, als atoi.
glaub nicht.
-
> glaub nicht.
Doch:
std::stringstream
#include <iostream> #include <sstream> int main() { std::string buf; std::cin >> buf; std::stringstream s1; s1 << buf; int var; s1 >> var; std::cout << var; }
-
Und warum ist das jetzt einfacher erst noch einen stream zu erzeugen und dann den string rein zu stecken um dann nen int raus zu holen, statt ne Funktion aufzurufen?
-
Was gibt's einfacheres als Streams, mit denen man als C++ Programmierer ja vertraut ist?
atio ist C und nicht C++. atoi ist gegen Overflows unsicher.char nummer_cstr[] = "12345678901234567890"; int nummer = atoi(nummer_cstr); // endet mit undefiniertem verhalten
atoi warnt nicht mal, wenn Fehler auftreten. atoi ist veraltet und wurde durch strtol() ersetzt.
-
Ad aCTa schrieb:
Was gibt's einfacheres als Streams, mit denen man als C++ Programmierer ja vertraut ist?
atoi natürlich.
atio ist C und nicht C++.
Echt? Isses nicht mehr in cstdlib drin?
atoi ist gegen Overflows unsicher.
Echt?
Hab ich dannOn success, the function returns the converted integral number as an int value.
If no valid conversion could be performed, a zero value is returned.
If the correct value is out of the range of representable values, INT_MAX or INT_MIN is returned.falsch verstanden? Ist aber egal, ich fange solche Fehler eh nicht ab.
atoi ist veraltet und wurde durch strtol() ersetzt.
Och, ich hab atoi immer noch lieb. strtol ist auch ganz toll. Je nach Anwendung kann man ja das besser passende nehmen.
-
Ad aCTa schrieb:
> glaub nicht.
Doch:
std::stringstream
#include <iostream> #include <sstream> int main() { std::string buf; std::cin >> buf; std::stringstream s1; s1 << buf; int var; s1 >> var; std::cout << var; }
Die Frage, was noch einfacher ist, hiermit zu beantworten ist... na ja... made my morning!
P.S.: Wenn du keine Funktionsrückgaben checkst, solltest du vielleicht einfach keine Funktionen nutzen. Sicherer gehts dann wohl nicht mehr...
-
Seht Euch mal http://www.boost.org/doc/libs/1_40_0/libs/conversion/lexical_cast.htm an.
Das ist sicher nicht der einfachste Weg, in Form von möglichst wenig Code Zeilen, aber ein großer Vorteil liegt darin, dass ich ganz schnell den Datentyp wechseln kann, in den ich den String casten will.
-
Ist mir ja fast schon peinlich...
Aber wenn ich atoi in einem Text mit Leerzeichen verwenden will, wird immer nur das erste Glied zu int. ich arbeite mit getline(cin,text) und lese Zahlen getrennt durch Whitespaces ein zb. 13 35 56 23 ,jetzt wird aber nur 13 zu intWer kann helfen?
-
n00b42 schrieb:
Ist mir ja fast schon peinlich...
Aber wenn ich atoi in einem Text mit Leerzeichen verwenden will, wird immer nur das erste Glied zu int. ich arbeite mit getline(cin,text) und lese Zahlen getrennt durch Whitespaces ein zb. 13 35 56 23 ,jetzt wird aber nur 13 zu intWer kann helfen?
Na ja, was erwartest du denn? Das atoi mehrere Werte zurückgibt und an genausoviele ints verteilt (und außerdem errät, wieviele du gerne hättest)?
Wenn es sich um eine feste Struktur handelt, kannst du besser sscanf benutzen. Damit kannst du auch beliebig viele Werte aus deinem String holen.
-
Tja, dann nimm halt den stringstream:
#include <iostream> #include <sstream> #include <string> using namespace std; int main() { stringstream dateStream; dateStream << "2009/31/12"; char c; int year, month, day; dateStream >> year; cout << "Year: " << year << endl; dateStream >> c >> month; cout << "Month: " << month << endl; dateStream >> c >> day; cout << "Day: " << day << endl; return 0; }
Und wenn es nur durch leerzeichen getrennt ist, gehts noch leichter:
int main() { string s = "23 34 45 56"; int i1, i2, i3, i4; stringstream str(s); str >> i1 >> i2 >> i3 >> i4; cout << i1 << " " << i2 << " " << i3 << " " << i4 << endl; }
-
dankeschön das war ne blöde Frage aber es geht weiter:
Hab ein Programm geschrieben das den String an den Leerzeichen zerhackstückselt und dann in int's verwandelt:#include <iostream> #include <string> #include <cstdio> #include <stdlib.h> using namespace std; int main () { string text; string zeichen[100]; int pos[100]; int lustig[100]; pos[1]=0; int loop; getline(cin,text); for (loop=2;loop<10;++loop) { pos[loop]=text.find(" ",pos[--loop]); zeichen[loop]=text.substr(pos[--loop],pos[loop]); cout<<zeichen[loop]<<endl; lustig[loop]=atoi(zeichen[loop].c_str()); cout<<lustig[loop]; } }
Er ist sicher unnötig kompliziert und so geht mir aber ums Prinzip:
folgende (sicherlich nicht unbekannte) Fehlermeldung:
this application has requested the runtime to terminate it in an unusual wayWas los?
achja, ich arbeite mit Dev-C++ von Bloodshed
-
Wass sollen denn die beiden --loop bei dir machen?
Du dekrementierst deine Schleifenvariable in der Schleife also zwei mal. Dadurch läuft deine Schleife rückwärts statt vorwärts.
-
Wird loop durch --loop etwa als 1 kleiner definiert oder bleibt loop die gleiche Zahl, es wird nur mit einer um 1 kleineren gerechnet?
-
Die Frage, was noch einfacher ist, hiermit zu beantworten ist... na ja... made my morning!
"Einfach" ist mal wieder mehr als subjektiv. Ich finde einen Funktionsaufruf nicht unbedingt einfacher als Variablen in einen Stream einmal hin und zurück zu schieben, höchstens kürzer.
Ist aber egal, ich fange solche Fehler eh nicht ab.
Was? Du fängst Fehler bei der Nutzereingabe nicht ab? Lässt du das Programm dann einfach durchrasseln/weiterlaufen mit diesem Wert? Die Doku sagt's ja schon, entweder MIN o. MAX, das weiß keiner so genau...
Auf Linux wird errno nicht beeinflusst:> The function atoi() need not affect the value of errno on an error.
(jeden Falls muss es nicht sein, wieder so schwammig ausgedrückt)
Auf Windows wird es auf ERANGE gesetzt:MSDN:
> In all out-of-range cases, errno is set to ERANGE.
Das reicht mir schon längst, um auf eine sichere und OS/Compilerunabhängige Alternative wie Stringstreams zurück zu greifen (auf der lexical_cast auch in vielen Implementierungen basiert).
Und überhaupt, was bringt es bitte, einem Anfänger den C-Stil in C++ zu legitimieren. Wenn ein Anfänger C-Strings benutzt, meckert das halbe Forum,
std::string
zu benutzen, aber hier wird nicht einmal erwähnt, dasatoi
keine gute Methode ist, Lexikalisch zu casten.So, nun zu dir: du solltest etwas mit dem Debugger rübergehen, der dir nicht von Dev-C++ geboten werden kann. Außerdem würde ich deinen Code jetzt nicht mehr einfach nennen, schau dir mal die Lösung an:
#include <iostream> #include <vector> #include <stdexcept> #include <sstream> using namespace std; int my_atoi(const string &s) { stringstream sstr; sstr << s; int i; sstr >> i; if(sstr.fail()) throw overflow_error("The number is invalid. (too big?)."); return i; } vector<string> split(const string &s, const char sep) { vector<string> v; string tmp; for(size_t n = 0; n < s.length(); n++) { if(s[n] == sep) { v.push_back(tmp); tmp.clear(); } tmp.push_back(s[n]); } v.push_back(tmp); return v; } int main() { string buf; getline(cin, buf); vector<string> v = split(buf, ' '); for(vector<string>::const_iterator iter = v.begin(); iter != v.end(); iter++) { try { int res = my_atoi(*iter); cout << res << endl; } catch(const overflow_error &e) { cerr << e.what() << endl; } } }
So läuft auch nach einer falschen Eingabe das Programm korrekt weiter.
-
Geht es etwa gar nich mit atoi(), ich habs jetzt so geändert:
#include <iostream> #include <string> #include <cstdio> #include <stdlib.h> using namespace std; int main () { string text; string zeichen[100]; int posi[100]; int lustig[100]; posi[1]=0; int loop; getline(cin,text); for (loop=2;loop<10;++loop) { posi[loop]=text.find(" ",posi[(loop-1)]); zeichen[loop]=text.substr(posi[(loop-1)],posi[loop]); cout<<zeichen[loop]<<endl; lustig[loop]=atoi(zeichen[loop].c_str()); cout<<lustig[loop]; } return 0; }
es funktioniert nur seeeehhhhhhhhhhr komisch, probiert es einfach aus. Ich sehe jedoch meinen Fehler nicht.
Soll ich auf Visual-C++ umsteigen?
-
Was soll'n das werden? oO (Habe nicht den kompletten Thread durchgelesen)
-
Kóyaánasqatsi schrieb:
Was soll'n das werden? oO (Habe nicht den kompletten Thread durchgelesen)
Naja, an den Leerzeichen wird der String in Teile geschnitten und dann in int's übersetzt und ausgegeben.
Versuchs nachzuvollziehen.
-
n00b42 schrieb:
Naja, an den Leerzeichen wird der String in Teile geschnitten und dann in int's übersetzt und ausgegeben.
Versuchs nachzuvollziehen.Und was war jetzt nochmal der tiefere Grund, warum du das so semi-manuell machen willst, anstatt stringstream zu benutzen, das optimal für diesen Zweck geeignet ist?