getline



  • Hallo,

    ich habe ein Problem mit folgendem Code:

    #include <iostream>
    using namespace std;
    
    int main ()
    {
        char array[40];
        cout << "Bitte 1. Text eingeben:\n";
        cin.getline(array, sizeof(array),'.');
        cout << "1. Eingabe war:\n " << array << '\n';
        cin.seekg(0,ios::end);
        cout << "Bitte 2. Text eingeben:\n" ;
        cin.getline(array, sizeof(array),'.');
        cout << "2. Eingabe war:\n " << array << '\n';
    }
    

    Normalerweise sollte hier eine zweite Eingabeaufforderung durchgeführt werden. Jedoch wird diese übersprungen (scheinbar) und das Programm abgebrochen. Wieso verhält sich obiger Code nicht wie erwartet.
    Zum Vergleich die Ausgabe:

    Bitte 1. Text eingeben:
    abc.def
    1. Eingabe war:
     abc
    Bitte 2. Text eingeben:
    2. Eingabe war:
    
    Press ENTER to continue.
    

    Gruß!



  • *push*



  • vermutlich musst du erstmal den eingabepuffer leeeren 🙂



  • Das hab ich auch mittels
    cin.seekg(0,ios::end);
    gemacht, oder besser:
    Damit werden die noch vorhandenen Zeichen im Eingabepuffer übersprungen.

    Das Beispiel stammt übrigens vom cpp-tutor.
    Vgl. www.cpp-tutor.de/cpp/le04/le04_02_d1.htm
    Daher wundere ich mich, dass das nicht so funktioniert, wie dort angegeben...



  • cin.clear();
    cin.ignore();
    

    damit leert man normalerweise den Puffer



  • Hallo,
    danke schön, ignore() funktioniert. Nur warum funktioniert der Code im Tutorial nicht? Ist dieser veraltert oder plattformspezifisch?

    Gruß



  • Zarathustra schrieb:

    ignore() funktioniert. Nur warum funktioniert der Code im Tutorial nicht? Ist dieser veraltert oder plattformspezifisch?

    Falls Du den MS VC 6 benutzt; so liegt es daran. In der mitgelieferten STL ist die Methode getline buggy.

    Gruß
    Werner



  • Hmm, ich verwende denn GCC (siehe unten). Kann doch nicht sein, dass zwei Compiler buggy sind oder doch?
    Gruß!

    g++ (GCC) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
    Copyright (C) 2006 Free Software Foundation, Inc.
    Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
    gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.



  • es wird wohl am '.' liegen.



  • Zarathustra schrieb:

    danke schön, ignore() funktioniert. Nur warum funktioniert der Code im Tutorial nicht? Ist dieser veraltert oder plattformspezifisch?

    "seekg(0,ios::end)"; setzt die Leseposition (seekg = seek get) auf das Byte Nr. x. (erstes Byte hat die Nr. '0'.) Mit seekg kann man absolut auf ein bestimmtes Byte und relativ vom Anfang, vom Ende und von der aktuellen Position her positionieren:

    cin.seekg (xnr, ios::end);
    

    positioniert relativ zum Ende.

    Mit

    cin.seekg (0, ios::end);
    

    wird auf das ende des Eingabepuffers positioniert, mit

    cin.ignore();
    

    wird der eingabepuffer geleert.

    ➡ letztendlich versetzt cin.clear() cin wieder in den Anfangsstatus (zB Fehler werden wieder zurückgesetzt). cin.ignore(); löscht alle Zeichen die noch im Einagebpuffer stehen.



  • @double*T

    Wie ignore() und clear() funktionieren ist mir schon klar. Nur frage ich mich, ob der Code im Tutorial falsch ist. Mit seekg (s.o.) wird in diesem Fall der Rest der Eingabe "übersprungen", daher sollte dieses Verhalten normalerweise nicht auftreten. Ich frage mich nur, warum sich das Programm nicht so verhält wie erwartet?!

    Gruß!



  • also wenn ich das Verhalten von getline() richtig kapiert hab dann passiert folgendes in deinem programm:

    - erster Aufruf von getline(): nichts im streambuf, also wird gewartet bsi der User was eingibt. Nach Eingabe wird bis zum Punkt ausgelesen, der Punkt wird verworfen -> erste Eingabe war "abc"
    - seekg(): der Lesezeiger im buffer von cin wird hinter das letzte Zeichen im Input gesetzt (in deinem Beispiel hinter das f)
    - zweiter Aufruf von getline(): es sind noch Zeichen im streambuf, also wird nicht auf Eingabe gewartet. Daher wird sofort bis zumnaechsten Puntk oder bis zum Ende des Buffers ausgelesen. Da der Lesezeiger schon am Ende steht, wird nichts ausgelesen und array[0] == '\0' -> zweite Eingabe war ""

    Ich denke mal dass du entweder das Beispiel aus dem Tutorial abgeaendert hast oder dass das Beispiel fehlerhaft ist. Im uebrigen wuerde ich lieber std::string an Stelle eines char-Arrays nutzen...



  • @pumuckl:
    Gut, dann war wohl das Beispiels fehlerhaft. std::string kenn ich leider (noch) nicht.

    Danke Schön!



  • Zarathustra schrieb:

    std::string kenn ich leider (noch) nicht.

    Dann wirds aber Zeit! Ich hoffe du hast nicht eines der Tutorials erwischt die erstmal mit char-Arrays herumwerkeln wo doch das Arbeiten mit std::string nicht nur fuer Anfaenger sher viel einfacher und vor allem sicherer ist...

    /edit: naja ok, strings werden dann in Kapitel 6 eingefuehrt. Evtl lohnt sich das, einen Abstecher dorthin zu machen 😉



  • Im Tutorial heisst es hierzu auch:

    Die nachfolgenden Ausführungen dienen eigentlich nur zur Übung im Umgang mit Feldern. C++ besitzt auch eine Standard Bibliothek die Verarbeitung von Strings erheblich vereinfacht. Mehr dazu aber nachher noch. Viele ältere (und leider auch neuere) C++ Programme legen Strings aber immer noch in char-Feldern ab.

    Also kein Grund zur Aufregung ... 🙂


Anmelden zum Antworten