🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: de.comp.lang.c++
Article #1670

Re: IOSTREAM.H

#1670
From: Jochen Diener
Date: Thu, 15 Feb 1996 00:00
128 lines
5677 bytes
pyro@gumption.ruhr.de schrieb in der Mail vom 13.02.96
zum Thema "IOSTREAM.H":

pyro@gumption.ruhr.de schrieb in der Mail vom 13.02.96
zum Thema "IOSTREAM.H":

> Da ich nicht über diverse Büchersammlungen verfüge,
> kann ich leider nicht nachsehen.
Du brauchst keine Buechersammlung. Nur die Onlinehilfe, den Stroustrup und
die Draft. Zumindest den Stroustrup solltest du dir kaufen, auch wenn du ihn
jetzt am Anfang noch nicht voll nutzen kannst ist er allein schon wegen des
ARM das Geld wert (denke auch immer an den ANSI-Draft wenn du das ARM
liest).

> Mein C++-Kursleiter wußte auf anhieb keine Erklärung.
Das Problem ist nicht so einfach beantwortbar, aber sicherlich haette dein
Kursleiter eine oder mehrere Loesungsansaetzte liefern muessen. Oder macht
er selbst den Kurs erst zum ersten mal _mit_ ?                    

Streams:
#include <iostream.h>
#include <conio.h>

//#define EXAMPLE1
#define EXAMPLE2

#ifdef EXAMPLE1
void main(void)
{
	char Buchstabe;

	cout << "\nBuchstabe : ";
	cin >> Buchstabe;
	cout.put(Buchstabe);

	// getch(); // Buchstabe erst nach Return ausgegeben da keiner 
                    // genau sagen kann was da so passiert, weil du C und
                    // C++ mixt. Sollte man generell nie tun.
        cin.get();  // Kaum macht mans richtig, schon gehts :-)
}
#endif

#ifdef EXAMPLE2
void main(void)
{
	char Buchstabe;
	cout << "\nBuchstabe : ";
	cin >> Buchstabe;

	cout.put(Buchstabe);
        cout << Buchstabe;  // es wird korrekterweise zweimal Buchstabe
                            // ausgegeben
	// getch();
        cin.get();
}
#endif

Zwar sollten die C-printf()-Familie mit den C++-Stream-I/O
gemeinsam verwendet werden koennen, da C und C++ oft gemischt werden, jedoch 
wuerde ich mich nicht darauf verlassen. Denn es gibt auch einen ANSI-C
Standard der schon von den C-Compilern nie so ganz unterstuetzt wurde.
Auf obiges Problem angewandt. Wer welchen Puffer wie liest und wann ist
Implementierungssache und deshalb nicht vorhersagbar, deshalb solltest
Du getchar()  druch  cin.get() ersetze.
Genrell ist nur festgelegt dass cout.put() in den Ausgabesteam schreibt, der
Rest ist dann Sache des streams.

Noch etwas Background, schoene gruesse an den Kursleiter.
cout ist ein Objekt der Klasse ostream_withassign, und wird waehrend der 
Initialisierung mit der Standard-Ausgabe verbunden. Der Unterschied zu cerr 
und clog liegt in der internen Arbeitsweise. Bei cerr (Fehlerausgaben) ist 
sichergestellt, dass bei einer Ausgabe ueber cerr kein Speicher vom Heap 
geholt wird, so dass cerr auch bei Heapueberlauf funktioniert. Ferner sind 
cerr und clog ungepuffert, d.h. auszugebende Daten werden ohne Zwischen-
speicherung an das Ziel weitergegeben.
Eine Pufferung erfolgt hauptsaechlich aus Performance Gruenden in 
groesseren Einheiten, welche in den Streams zwischengepuffert werden. Bei 
Eintreten bestimmter Bedingungen (z.B: Puffer voll) wird dieser dann ganz 
weggeschrieben. Hierbei kann die Puffergroesse varieren, so dass es bei
verschiedenen Compilern und Systemen zu unterschiedlichen Zeitpunkten zur
Ausgabe des Puffers kommen kann.
Die Aufagabe der Pufferdatenblockverwaltung uebernehmen Ableitungen der 
abstraken streambuf Klasse (z.B. stdiobuf <stdio.h>).
Die Standardstreams cin und cout sind verbunden (tied), so dass sichergestellt
ist, dass alle an cout uebergebenen Zeichen auch tatsaechlich auf 
dem Bidschirm ausgegeben werden, bevor eine Eingabe ueber cin oder Ausgabe 
ueber clog, cerr durchgefuehrt wird (Erklaerung fuer oben).  
Dieses Verhalten koennte natuerlich auch von Compiler und System abhaengig 
sein, so dass man es immer testen sollte (Anm. von jemand der portable
Programme schreibt und weis, dass alles anders ist wie es sein sollte).

Vielleicht baut ihr am besten im Kurs ein Arrayklasse die ihr ueber euren 
eigenen stream ausgebt, dann kannst du es.
Ein Beispiel, das das Problem vielleicht noch etwas verdeutlicht und zum
Testen animieren soll:
ofstream myOut(0); //stdout
istream  myIn(1);  //stdin

int dummy;
myOut << endl << "Hallo";
myIn >> dummy;
myOut << "Dummy=" << dummy << endl;

Bei Programmstart ist der Bildschirm leer weil "Hallo" noch im Puffer von 
myOut steht, obwohl myIn schon auf Daten von der Tastatur wartet. Erst am 
Programmende (Destruktor aufruf) wird der Puffer ausgegeben.
Loesung:
a) explizit leeren mit 
   myOut << endl << "Hallo" << flush;
b) Eine tie zwischen myIn und myOut
   myIn.tie(&myOut);

So und nun probieren und testen...    

Falls du eine Anspruchvolle Anwendung fuer deine eigene Streamklasse suchst,
ueberlege dir mal wie du eine Streamklasse aufbauen wuerdest die Objekte
(einfache Datentypen, Beaume, Listen, bel. Klassen) persistent abspeichert
(denke auch an virtuelle Funktionen und Pointerstrukturen) und als Schmankerl
diese noch binaerkompatibel, zum Datenaustausch zwischen verschiedenen
Betriebssystemen, abspeichern kann....

Hoffe dein Kopf qualmt nicht zu sehr, bis dann
 	Jochen


--
Es gibt keine Probleme nur Loesungen! Nur werden die meist zu Problemen...:-)
Mail: j.diener@hit.handshake.de  
Technical Details
Message-ID: <62tXlkEd6JB@hit028.hit.handshake.de>
Path: arc1-ca.pugleaf.net!hit.sb.sub.de!j.diener
References: <62mRM9kpa8B@gumption.ruhr.de>

Show Full Headers
Complete Article Headers
X-Mailer: CrossPoint v3.1 R/A12197
Message-ID: <62tXlkEd6JB@hit028.hit.handshake.de>
X-Gateway: ZCONNECT UR hit.sb.sub.de [DUUCP BETA vom 16.01.1996]
References: <62mRM9kpa8B@gumption.ruhr.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
From: j.diener@hit.handshake.de (Jochen Diener)
Subject: Re: IOSTREAM.H
Date: 15 Feb 1996 00:00:00 +0000
Path: arc1-ca.pugleaf.net!hit.sb.sub.de!j.diener
Newsgroups: de.comp.lang.c++
Distribution: world