Forum: PC-Programmierung Frage zu cin.get()


von anfänger (Gast)


Lesenswert?

>>Zitat

cin.get();
Dieser Befehl wartet auf ein Enter und schluckt es dann. Das Problem 
damit ist wenn du vorher schon einmal mit cin etwas eingelesen hast wie 
deine Variable dann fängt es das Enter davon auf. Deshalb musst du den 
Befehl einfach 2x verwenden, dann fängt er beim ersten mald as letzte 
Enter ab und das 2. mal wartet dann auf ein neues Enter. "
>>Zitat Ende
1
#include "stdafx.h" 
2
#include <iostream> 
3
4
using namespace std; 
5
6
int main () 
7
8
{ 
9
10
    float a=0,b=0,c=0,e=0,f=0; 
11
12
    cout << "geben sie 4 zahlen ein die ersten beiden werden addiert"<<endl; 
13
    cin >>a; 
14
    cin >>b; 
15
    cin >>e; 
16
    cin >>f; 
17
    c=a+b; 
18
    cout << "das ergebniss ist :"<<c<<endl; 
19
    
20
    
21
22
cin.get(); 
23
cin.get(); 
24
25
    return 0; 
26
}
nach dem Zitat oben bräuchte ich bei diesem Beispiel aber dann mehr als 
zwei "cin.get();"
weshalb reichen hier zwei??

von ...... (Gast)


Lesenswert?

Dieses globale using namespace solltest du vermeiden.
Ansonsten funktioniert hier folgendes:
1
#include <iostream> 
2
3
int main (int argc, char * argv[]) 
4
{ 
5
   using namespace std; 
6
   float a = 0, b = 0, c = 0, e = 0, f = 0; 
7
8
   cout << "geben sie 4 zahlen ein die ersten beiden werden addiert"<<endl; 
9
   cin  >> a; 
10
   cin  >> b; 
11
   cin  >> e; 
12
   cin  >> f; 
13
   c = a + b; 
14
   cout << "das ergebniss ist :" << c << endl; 
15
16
   cin.ignore(256, '\n');
17
   cin.get(); 
18
19
   return 0; 
20
}
Kannst du im Beitrag "C++ Programm soll nicht automatisch gesclossen werden!" auch 
nochmal nachlesen.

von anfänger (Gast)


Lesenswert?

Danke !
Dies beantwortet jedoch nicht meine Frage.
Die war lautete so: "nach dem Zitat oben bräuchte ich bei diesem 
Beispiel  dann aber mehr alszwei "cin.get();"
Weshalb reichen hier zwei?

von Karl H. (kbuchegg)


Lesenswert?

Stell dir die Reihenfolge der Ereignisse vor.

In deinem Beispiel gibst du ein:
4 Zahlen, wobei jede Zahl mit einem Enter abgeschlossen wird.
Danach drückst du nochmal Enter um das Programm zu beenden.

Soweit so gut.
Wie arbeitet
  cin >> a
?

Das Einlesen vom Stream beginnt damit, dass Whitespace-Character (also 
Leerzeichen Tabulatoren, Enter und dergleichen überlesen werden). Es 
wird weiter solange vom Stream gelesen, bis es auf ein Zeichen trifft, 
welches nicht mehr zur Eingabe gehören kann. Dieses Zeichen wird aber 
nicht aus dem Stream entfernt, sondern verbleibt im Stream, so dass die 
nächste Leseoperation es sich holen kann.

Und jetzt gehen wir das mal durch

Dein Programm startet

Es kommt an die Stelle  cin >> a. Also wartet das Programm.
Du gibst ein:  25 Enter
Das cin >> a holt sich die Zeichen 2 und 5 und weist der Variablen a den 
Wert 25 zu. Das Enter dient als Abbruch Kriterium für die Zahl und 
verbleibt als solches im Stream

Das Programm kommt zu  cin >> b.
Die Leseoperation sieht als erstes das Enter von vorhin und ignoriert 
es, weil ja vor dem Einlesen einer Zahl erst mal alle Whitespace 
Character ignoriert werden.
Weiter findet sich aber nichts im Stream, daher wartet das Programm auf 
deine Eingabe.
Du gibst ein: 38 Enter
Die Zeichen 3 und 8 werden wieder als Eingabe für b aufbereitet, b 
bekommt 38, das Enter als nicht mehr zur Integer Eingabe gehörendes 
Zeichen verbleibt im Stream

Nächstes Anweisung  cin >> e
Wieder das gleiche Spielchen: Das Enter welches noch im Eingabestream 
auf seine Bearbeitung wartet, wird ignoriert und da sich nichts weiter 
im Stream findet, wartet das I/O System erst mal auf deine Eingabe. 
Wieder das gleiche Spielchen, du gibst ein 58 Enter
Die 5 und 8 werden genommen um für e die Zahl 58 zu bauen, das Enter, 
welches nicht zur Zahl gehören kann, wird wieder in den Eingabestream 
zurückgestellt und wartet.

Was bei cin >> f passiert kannst du dir jetzt schon denken.
Von deiner Eingabe "73 Enter" wird wieder 7 und 3 genommen um f zu 
besetzten, während das Enter auf seine weitere Bearbeitung im Stream 
wartet.

Und dann kommt das erste cin.get()
Dieses findet das Enter, welches noch von der vorhergehenden Eingabe auf 
seine Bearbeitung wartet und ist glücklich damit. Der get kommt sofort 
zurück. Und wenn jetzt nicht ein zweites cin.get() kommen würde, wäre 
damit dein Programm beendet.
Erst ein 2-ter nachfolgender cin.get() findet nichts mehr im Stream vor 
und muss daher auf eine Eingabe von dir warten.

Die Lösung die ...... vorschlägt ist die bessere.
Durch das ignore wird dem Stream gesagt: Schmeiss mal mehr oder weniger 
alles weg, was du im Stream hast (na ja nicht ganz: eigentlich steht da 
ignoriere alles bis zum und inklusive dem nächsten Enter) und stell erst 
mal gesicherte Zustände für einen leeren Stream her.

Du hast das Zitat da oben einfach nur falsch interpretiert. Das ist 
alles. Das Zitat sagt nichts anderes, als das du 2 cin.get() brauchst, 
wenn du unmittelbar vorher mindestens einmal mittels cin >> irgendwas 
eingelesen hast. Du brauchst deswegen 2 cin.get(), weil die letzte 
Leseoperation ein Enter im Stream zurückgelassen hat, welches noch nicht 
bearbeitet wurde. Das ist aber unabhängig davon, ob du zuvor 2 oder 2000 
Einleseoperation mittels cin >> a gemacht hast. Die letzte Operation 
hinterlässt das Enter im Stream und der erste cin.get() holt es sich 
sofort ohne auf eine Eingabe von dir zu warten.

von anfänger (Gast)


Lesenswert?

Vielen Dank für die ausführliche Antwort

von anfänger (Gast)


Lesenswert?

Reagiert cin.get ()
Nur auf enter oder auf  alle Whitespace Character?

von Karl H. (kbuchegg)


Lesenswert?

cin.get() reagiert auf jedes Zeichen, egal welches.

von anfänger (Gast)


Lesenswert?

/**2.  Schreiben Sie ein Programm, das zwei Zahlen einliest und je 
nachdem,
ob die erste Zahl kleiner, größer oder gleich der zweiten ist, 
verschiedene
Sätze auf den Bildschirm schreibt
(z.B.: „Beide Zahlen sind gleich“).**/



#include <iostream>
using namespace std;

int main ()

{
1
float zahl1;
2
float zahl2;
3
4
  cout << "Diees Programm  dient zum ermitteln des Groeßenverhätnisses zweier Zahlen!"<<endl
5
  <<"(Druecken Sie zum vortfahren eine Taste)";
6
  cin.get();
7
  cout << "Geben sie zahl Nr 1 ein"<<endl;
8
  cin>> zahl1;
9
  cout<<"geben sie eine zweite Zahl ein";
10
  cin>> zahl2;
11
    
12
    if (zahl1==zahl2)
13
    cout<<"Zahlen sind gleich";
14
15
      if (zahl2<zahl1)
16
      cout<< zahl1<<"ist größer als"<<zahl2;
17
18
        if (zahl1<zahl2)
19
        cout<<zahl1 <<"ist kleiner als"<< zahl2; 
20
21
  return 0;
22
}
Schon lang her aber was ich vor langem schon schrewiben wollte:
Hier reagiert "cin.get ()"  aber nur auf Enter!
Vielleicht habe ich sie aber auch Falsch veranden!

Gruß

von Sven P. (Gast)


Lesenswert?

Ich würde auch mal darüber nachdenken, was 'Enter' eigentlich bewirkt. 
Unter Linux landet einmal Enter als Ascii '10' (LF) im Stream. Unter 
Windoof vermutlich als Ascii '13 10' (CR+LF).

Und wenn cin.get() nur auf Enter reagiert, liegt das daran, dass die 
Konsole einen Zeilenpuffer hat und erst dann die Zeichen in den Stream 
leitet, wenn eine Zeile vollständig ist, wenn als Enter gedrückt wurde. 
Unter Linux kann man den mit stty und Konsorten abstellen, unter Windoof 
kenne ich mich damit nicht aus.

Zwei float-Werte mit '==' zu vergleichen ist übrigens absoluter 
Bockmist. Floats sind im Allgemeinen absoluter Bockmist, aber das isn 
andres Thema :-)

von Karl H. (kbuchegg)


Lesenswert?

anfänger wrote:

> Hier reagiert "cin.get ()"  aber nur auf Enter!
> Vielleicht habe ich sie aber auch Falsch veranden!

Das liegt aber nicht am cin.get(), sondern am ganzen Stream Unterbau und 
wie der Eingaben buffert.

Wenn eine Eingabeoperation warten muss, weil der Buffer erst gefüllt 
werden muss, dann warten die Bufferungsoperationen bis ein Enter 
daherkommt.

Am Beispiel obigen Programms:

Kommt am Anfang die Abfrage
"(Druecken Sie zum vortfahren eine Taste)"

dann einfach mal folgendes eingeben:
ein Leerzeichen (damit der cin.get() befriedigt wird) und gleich daran 
anschliessend eine Zahl, zb. 123 und dann erst Enter.

Durch den Enter wird der Bufferungsmechanismus getriggert, der die 
wartende Eingabeoperation angehalten hat, bis er einen Enter sieht. In 
dem Fall wird dann das erste eingegebene Zeichen, das Leerzeichen dem 
cin.get() zur Verfügung gestellt. Gleich danach kommt die Abfrage nach 
der ertsen Zahl. Auch da liegt noch was im Buffer, nämlich 123, welches 
dem cin>> zahl1; übertragen wird, ohne dass an dieser Stelle der 
Benutzer erneut etwas eingeben muss. Danach kommt die Abfrage nach der 
zweiten Zahl. Im Eingabebuffer liegt nichts mehr vor, also wird wieder 
auf den Benutzer gewartet, bis er die zweite Zahl eingegeben hat und die 
Eingabe mit Enter abgeschlossen hat.

Man kann sogar soweit gehen, bei der allerersten Abfrage
"(Druecken Sie zum vortfahren eine Taste)"

die Eingabe
a123 456 <Enter>
zu machen. Dann wartet das Programm überhaupt nicht mehr auf weitere 
Benutzereingaben. Das 'a' befriedigt den cin.get(), beim cin >> zahl1 
wird die 123 aus dem Eingabepuffer geholt und beim cin >> zahl2 die 456

Ein <Enter> ist also deshalb ein bischen speziell, weil es 2 Aufgaben 
erfüllt. Zum einen kommt es als normales Zeichen in den Eingabestrom, 
zum anderen teilt es dem Buffermechanismus mit, dass eine Eingabe soweit 
vollständig ist, und der Buffermechanismus anfangen kann, die 
eingegebenen Zeichen an die aufrufenden Leseoperationen weiterzuleiten.

Aber mit dem cin.get() hat das alles nichts zu tun. cin.get() holt sich 
einfach nur das nächste Zeichen aus dem Eingabestrom. Was auch immer 
dieses Zeichen ist. Unter Umständen kann es natürlich sein, dass der 
Buffer des Eingabestroms leer läuft und daher auf eine weitere 
Benutzereingabe gewartet wird, die dann mit Enter abgeschlossen werden 
muss, damit der Buffermechanismus anfängt Zeichen an die aufrufenden 
Lesefunktion auszugeben.

von Anfänger (Gast)


Lesenswert?

Ist eigentlich logisch :-)
Danke!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.