getline bug in Borland C++ Builder 5
-
Hallo,
ich habe in meinem Programm so eine Konstruktion:
for(int i=0;i<max;i++) { cout << "Name: "; getline(cin,name); cout << "Vorname : "; cin >> vorname; cout << "Wohnort : "; cin >> wohnort; person_out[i] = CPerson(name,vorname,wohnort); }
Der erste Schleifendurchlauf klappt super aber schon beim zweiten Durchlauf wird dann die Eingabe vom Namen übergangen:
Name: Vorname:
So sieht das aus.
Ich habe mit google gesucht und mir ist dieser Bug auch in VC++ bekannt aber bei Borland bin ich immer davon ausgegangen das es diesen Bug nicht gibt. Ich habe diese Seite gefunden mit einer Anleitung die diesen Bug fixen soll http://users.telenet.be/davidswall/cpp/cppgetl.htm. Naja jedendalls habe ich den ersten Schritt auf dieser Seite ausgeführt und als es dann ums kopieren geht exestiert bei mir nicht das Verzeichniss "Source\RTL\Lib\" nicht. Wie kann ich diesen nervigen Bug beseitigen ?
mfg Charles Bronson
-
Whoaaaaa. Einmal hätt auch gereicht.
Was das Problem angeht, das ist kein Bug des Compilers, den hast du selbst verbockt. Wenn du die nächsten Zeilen auch mit getline eingelesen hättest, wäre kein newline mehr im stream und beim nächsten Schleifendurchlauf hätte alles wunderbar funktioniert.
-
Ups das wollte ich nicht das soviele Beiträge erstellt werden, nur wenn ich auf "absenden gedrückt habe" hat er den Post nicht abgeschickt. Sorry, Mods.
Ja aber es musste doch auch so klappen. Ich möchte nicht alles mit getline einlesen.
-
So kann es nicht klappen, aus dem einfachen Grund, dass
cin >> wohnort;
nur die nächste Phrase (also bis zum nächsten space, tab oder newline) einliest und dieses im Stream lässt. Mal ganz abgesehen davon, dass du damit Probleme haben dürftest, z.B. "Bad Pyrmont" einzulesen, ist das newline für das nächste getline also noch vorhanden.
-
was spricht dagegen?
.MamboKurt
-
Naja weil ich diese Schleife nur Testweise gebaut habe, später sollen auch Zahlen (PLZ, Haus Nr. Alter, usw) eingebenen werden. Und da benutze ich lieber cin.
-
Wie bereits gesagt, getline() ließt bis zum '\n'-Zeichen. Dieses bleibt jedoch noch im Puffer, weshalb die nächste cin>>Anweisung nicht 'funktioniert'. Um das zu verhindern musst du nach der getline()-Anweisung den Puffer leeren.
Z.B. mit cin.ignore()
cin.ignore(anzahl_der_zeichen_die_ignoriert_werden_sollen, bei_diesen_zeichen_wird_das_ignorieren_abgebrochen);
Dazu schaust du am besten mal hier: http://www.cppreference.com/cppio/ignore.html
Caipi
-
Vielleicht hilft dir das hier weiter:
#include <iostream> #include <sstream> #include <string> template<typename t> t read_type(std::string const &prompt = "", std::istream &in = std::cin) { std::string zeile; std::stringstream sstr; t ret; do { sstr.clear(); std::cout << prompt << std::flush; std::getline(in, zeile); sstr.str(zeile); sstr >> ret; } while(!sstr); return ret; } template<> std::string read_type<std::string>(std::string const &prompt, std::istream &in) { std::string s; std::cout << prompt << std::flush; std::getline(in, s); return s; } int main() { int x = read_type<int>("Zahl eingeben: "); std::string s = read_type<std::string>("Irgendwas eingeben: "); std::cout << "Zahl = " << x << std::endl << "Irgendwas = " << s << std::endl; }
Gebufferte Eingabe ist imho eh sinnvoller.
-
...oder, eigentlich noch sinnvoller:
#include <iostream> #include <sstream> #include <string> template<typename t> t read_type(std::string const &prompt = "", std::istream &in = std::cin, std::ostream &out = std::cout) { std::string zeile; std::stringstream sstr; t ret; do { sstr.clear(); out << prompt << std::flush; std::getline(in, zeile); sstr.str(zeile); sstr >> ret; } while(!sstr); return ret; } template<> std::string read_type<std::string>(std::string const &prompt, std::istream &in, std::ostream &out) { std::string s; out << prompt << std::flush; std::getline(in, s); return s; }
-
Mit ignore und den Eingabfunktionen habe ich ja jetzt schonmal ein paar Möglichkeiten um das Problem zu lösen. Danke :):):)