getline(): Eingabe vor Ausgabe der Eingabeaufforderung?
-
Hallo,
ich wollte einen String inklusive Leerzeichen (sprich eine ganze Zeile) in ein char-Array einlesen und habe auch schon ein bisschen herumgesucht hier im Forum.
Bin dann auf die getline Methode gestoßen, welche ja prinzipiell schonmal funktioniert.Weitere Probleme waren, dass frühere Eingaben mit cin noch Reste im Eingabepuffer liegen gelassen haben, welche ich per ignore() entfernt hab.
Soweit funktioniert das ganze im Prinzip auch... Das Problem ist, dass die Ausgabe der Eingabeaufforderung erst NACH der Eingabe ausgeführt wird, obwohl sie im Programm zuerst kommt:
const int STRING_SIZE = 30; long isbn; int price, pages, count; char *authors, *title, *publisher; authors = new char[STRING_SIZE]; title = new char[STRING_SIZE]; publisher = new char[STRING_SIZE]; cout << "ISBN? "; cin >> isbn; cout << "Price? "; cin >> price; cout << "Pages? "; cin >> pages; while (cin.peek() == '\n') cin.ignore(); cout << "Authors? "; cin.getline(authors, STRING_SIZE, '\n'); while (cin.peek() == '\n') cin.ignore(); cout << "Title? "; cin.getline(title, STRING_SIZE, '\n'); cout << "Count? "; cin >> count; while (cin.peek() == '\n') cin.ignore(); cout << "Publisher? "; cin.getline(publisher, STRING_SIZE, \n'); // zusammenfassende Ausgabe ...Die Ausgabe beim Programmablauf sieht nun aber so aus:
ISBN? 123 Price? 1 Pages? 2 EIngabe vor Ausgabe Authors? nochmals... Title? Count? 3 und hier auch Publisher? Books: Book: isbn: 123 price: 1.000000 pages: 2 authors: EIngabe vor Aus gabe title: nochmals... count: 3 publisher: und hier auchWieso erfolgt die cout-Ausgabe erst nach der Eingabe?
-
Weil die Konsolenausgabe auf den meisten Systemen gepuffert ist. Schieb nach der Eingabeaufforderung noch ein std::flush durch cout, dann sollte es gehen.
-
Ich hab eine Eingabe nun testweise verändert
cout << "Authors? "; flush(cout); cin.getline(authors, STRING_SIZE, '\n');Hab neu compiliert und trotzdem keine Veränderung... immernoch erfolgt die Ausgabe erst dann, wenn die Eingabe abgeschlossen wurde.
-
Das liegt daran das peek() blockiert und wartet bis eine Eingabe erfolgt. Ebenso wartet ignore() auf eine Eingabe.
Also wartet peek() auf input. Du schreibst etwas, peek sieht das das erste Zeichen kein Newline ist und überspringt das ignore und gibt die Eingabe gleich direkt an dein getline weiter. Daher kommt die Abfrage "vorher".
-
Ist zumindest mal ein erster nachvollziehbarer Ansatz, der das Verhalten erklärt... aber wieso wartet peek bis ich zum ersten Mal RETURN drücke? Sobald ich anfange, irgendwas zu tippen, müssten sich doch schon Zeichen im Puffer befinden, die != '\n' sind und dem entsprechend sollten dann sowohl peek() als auch die while Schleife verlassen werden.
-
nach den cin>>... Aufrufen ja, aber getline() löscht das Enter-Zeichen am Zeilenende. Außerdem arbeitet die Tastatur selbst auch gepuffert, d.h. deine Eingaben werden erst ans Programm (und peek()) übergeben, wenn du sie mit ENTER abgeschlossen hast.
-
CStoll schrieb:
nach den cin>>... Aufrufen ja, aber getline() löscht das Enter-Zeichen am Zeilenende.
Ok d.h. ich brauch nach den cin-Eingaben den Puffer nicht mehr nach Zeilenumbrüchen zu durchsuchen... scheint auch zu klappen.
Also habe ich meine cin.ignore-Aufrufe nur noch hinter die getline-Aufrufe gesetzt.
Kann es sein, dass getline alles im Eingabepuffer lässt?
2 direkt aufeinanderfolgende getline Aufrufe machen mir keine Probleme aber eine direkt auf getline folgende Eingabe mit cin >> xy wird sofort übersprungen... ich hab mir mal Testweise ausgeben lassen, was peek() so für ein Zeichen sieht kurz vor der cin Eingabe... dort war das Anfangszeichen der letzten Eingabe für getline gespeichert.Meine Vermutung ist nun, dass sich die ganze Zeile noch immer im Eingabepuffer befindet... wie bekomm ich die da raus, ohne auf einem blockierenden peek()-Aufruf zu Enden?
edit:
Hab noch ein bisschen herumgegoogelt und mich nun entschieden, nach jedem cin, was direkt vor einem getline-Aufruf kommt, den kompletten Eingabepuffer zurückzusetzen.cout << "Book " << i << ": \n"; cout << "ISBN? "; cin >> isbn; cout << "Price? "; cin >> price; cout << "Pages? "; cin >> pages; cin.seekg(0,std::ios::end); cin.clear(); cout << "Authors? "; cin.getline(authors, STRING_SIZE, '\n'); cout << "Title? "; cin.getline(title, STRING_SIZE, '\n'); cout << "Count? "; cin >> count; cin.seekg(0,std::ios::end); cin.clear(); cout << "Publisher? "; cin.getline(publisher, STRING_SIZE, \n');Das funktioniert genau nach meinen Vorstellungen... Wer möchte, kann ISBN, Preis und Pages "in einem Rutsch" mit Leerzeichen getrennt eingeben aber vor dem getline Aufruf wird alles weitere aus dem Puffer geschmissen ^^
Thx für die Hilfe
