atoi() Frage
-
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?
-
Was passt dir an adatcas Ansatz nicht???
-
n00b42 schrieb:
Geht es etwa gar nich mit atoi(), ich habs jetzt so geändert:
Doch, klar. Aber wenn Du mehrere einliest, sind streams doch angemessener, oder?
-
ja sicher aber was stimmt dadran nich???
#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; }
-
n00b42 schrieb:
ja sicher aber was stimmt dadran nich???
#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; }
Hi,
dein Code ist total unlesbar. Auch die Einrückung ist dir nicht wirklich gut gelungen
Außerdem ist dein Ansatz zur Lösung des Problems nicht sonderlich schön, da du es dir viel zu kompliziert machst.So könnte man es machen, aber das empfinde ich als total umständlich:
#include <iostream> #include <string> int main() { std::string text; // Der eigentliche Text std::getline(std::cin, text); // einlesen std::string temp; for (unsigned int i = 0; i < text.length() + 1; ++i) { if (text[i] == ' ' || text.length() == i) { std::cout << atoi(temp.c_str()) << std::endl; temp = ""; } else { temp += text[i]; } } return 0; }
Folgender Code macht das gleiche, aber viel besser:
#include <iostream> #include <sstream> #include <string> int main() { std::string text; // Der eigentliche Text std::getline(std::cin, text); // einlesen int number; std::stringstream strm(text); while (strm >> number) { std::cout << number << std::endl; } return 0; }
-
Und dazu ergänzend ein Beispiel aus der STL Doku von sgi, das den istream_iterator nutzt (http://www.sgi.com/tech/stl/istream_iterator.html) und dann man hat die Werte auch in einem vector:
vector<int> V;
copy(istream_iterator<int>(strm), istream_iterator<int>(), back_inserter(V));
-
langsam hab ich das Gefühl ich solte von Dev-C++ 4.9.9.2 auf was andres umsteigen.
Kann mir da jemand einen Tipp geben?
-
n00b42 schrieb:
langsam hab ich das Gefühl ich solte von Dev-C++ 4.9.9.2 auf was andres umsteigen.
Kann mir da jemand einen Tipp geben?Code::Blocks natürlich. Oder falls Du einen brutal schnellen Rechner hast eine Java-IDE wie Netbeans oder Eclipse.
-
Und hier noch ein Beispiel ohne streams mit einem formschönen C Style Cast:
void example ( char* s ) { while (*s) printf("%ld\n", strtoul ( s, &s, 10 ) ); } int main() { string text("1 12 123"); example ( (char*)text.c_str() ); return 0; }