Article View: de.comp.lang.c++
Article #1670Re: IOSTREAM.H
From: Jochen Diener
Date: Thu, 15 Feb 1996 00:00
Date: Thu, 15 Feb 1996 00:00
128 lines
5677 bytes
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.dienerReferences:
<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