Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » cin.sync() scheint nicht zu klappen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
27.11.2010, 18:04 Uhr
-Alex-



Hallo zusammen,

ich hab da ein komisches Problem: Ich wollte mir die genaue Wirkung von cin.sync() und cin.clear() klarmachen dazu hab ich folgendes gemacht;


C++:
#include <iostream>
#include <string>
using namespace std;

int main()
{
string s,a;
    getline(cin, s ,'.');
    cin.sync();
    cin.clear();
    cout << s;
    cin >> a;
    cout << a;
    return 0;
}



Bescheuert ist, dass unter Windows (Code Blocks mit mingw) das ganze klappt, d.h cin.sync leert den Puffer.

Unter Linux (Code Blocks mit gnu gcc) klappt das aber nicht. Da wird der Eingabepuffer nicht geleert; kann mir vielleicht jemand verraten, woran das liegen könnte? Ich bin echt ratlos...


Gruß Alex
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.12.2010, 11:42 Uhr
0xdeadbeef
Gott
(Operator)


Das liegt daran, dass das Verhalten für std::cin.sync() im Standard nicht definiert ist und die Konsole unter Windows scheinbar zufällig so funktioniert, dass es macht, was du erwartest.

std::istream::sync ruft, wenn der Eingabestrom gepuffert ist, rdbuf()->pubsync() auf. Die ist eine virtuelle Funktion von basic_streambuf<char>, deren Verhalten also vom konkreten Buffertyp abhängt. Die Default-Implementation in basic_streambuf greift in die Put-Area des Puffers ein und macht dementsprechend nur für Ausgabepuffer Sinn, dementsprechend ist std::istream::sync eigentlich nur dann von Interesse, wenn du die Semantik in einem eigenen Streambuffer-Typ selbst definierst und benutzt. In diesem Fall sollte die Methode den Eingabestrom mit der Quelle synchronisieren, was auch immer das im Einzelfall bedeutet.

Allerdings willst du im Zweifel auch nicht den gesamten Eingabepuffer wegschmeißen; was machst du, wenn beispielsweise jemand stdin in eine Datei umleitet? Es ist bei genauerer Betrachtung auch schwer zu definieren, was "den Eingabepuffer wegschmeißen" eigentlich genau bedeutet oder im Einzelfall macht.

Üblicherweise willst du an dieser Stelle Folgendes:

C++:
#include <limits>
#include <iostream>

// ...

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');


...was gaaaaanz viele Zeichen ignoriert, aber damit aufhört, wenn ein Zeilenumbruch gefunden wurde. Alternativ bietet es sich an, die Eingabe gleich zeilenweise zu verarbeiten. Ich habe dafür eine Funktionsvorlage rumliegen:

C++:
#include <iostream>
#include <sstream>
#include <string>

template<typename result_t>
result_t read_type_ref(result_t &dest,
               std::string const &prompt,
               std::istream &in  = std::cin,
               std::ostream &out = std::cout) {
  std::istringstream parser;
  std::string line;

  do {
    parser.clear();

    out << prompt << std::flush;

    std::getline(in, line);

    parser.str(line);
    parser >> dest;
  } while(!parser);

  return dest;
}

template<typename result_t>
result_t read_type(std::string const &prompt,
           std::istream &in  = std::cin,
           std::ostream &out = std::cout) {
  result_t result;
  return read_type_ref(result, prompt, in, out);
}


Zu Benutzen wie folgt:

C++:
int x = read_type<int>("Zahl eingeben: ");


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 13.12.2010 um 11:45 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: