Ein-/Ausgabe in C++ Übersicht

Transcription

Ein-/Ausgabe in C++ Übersicht
Ein-/Ausgabe in C++
Übersicht
• Ersatz für „stdio“ in C
– Typensicher
– Benutzt C++-Sprachfeatures
– Ein-/Ausgabe für selbstdefinierte Datentypen
– #include <iostream>
• Mehrere Ebenen
– streambuf
• Schnelle (gepuffer te), zeichenweise Ein-/Ausgabe
– istream, ostream
• Formatierte Ein-/Ausgabe
• iostream: multiple inheritance von istream und ostream
• Weitere abgeleitete Klassen (z. B. Ausgabe nach Strings)
© 2005 AG Rechnernetze
5-io.1
Ein-/Ausgabe in C++
Ausgabe
• Vordefinierte ostreams
ostream cout;
// Standard-Output
ostream cerr;
// Standard-Error-Output
• Ausgabe mit Insertion Operator
cout << "hello";
cerr << "x=" << x << ’\n’;
– Überladen für verschiedene Typen:
• char, unsigned char
→ Ausgabe des Zeichens
• char*, unsigned char* → Ausgabe des Strings
• arithmetische Typen
→ Ausgabe der Zahl
• bool
→ 0/1 oder true/false
• void*
→ Pointer-Wer t in Hex
• put und write
cerr.put(’\n’);
© 2005 AG Rechnernetze
cout.write("...", 3);
5-io.2
Ein-/Ausgabe in C++
Ausgabe
• Selbstdefinierte Datentypen ausgeben
ostream& operator<<(ostream &s, IntArray a) {
s << "[";
for (int i = 0, e = a.get_size()-1; i <= e; i++) {
s << a[i];
if (i < e) s << ’ ’;
}
return s << "]";
}
int main() {
IntArray my_array(10);
...
cout << my_array << endl;
}
© 2005 AG Rechnernetze
5-io.3
Ein-/Ausgabe in C++
Eingabe
• Vordefinierter istream
istream cin;
// Standard-Input
• Eingabe mit Extraction Operator
Coordinate pos;
cin >> pos.x;
cin >> pos.y;
– Whitespace wird überlesen
– Überladen für char, unsigned char, arithmetische Typen, bool, void*
– Achtung, keine binäre Eingabe:
char c;
cin >> c;
© 2005 AG Rechnernetze
// Whitespace wird überlesen!
5-io.4
Ein-/Ausgabe in C++
Fehlerbehandlung
• Fehler werden im Stream gespeichert
Stream-Zustand
good
eof
fail
bad
letzte Operation
war OK
war OK
war nicht OK
war nicht OK
nächste Operation
könnte klappen
geht schief
geht schief
Stream nicht mehr verwendbar
– Abfrage über bool-Memberfunktionen
if ((cout << x).good()) alles_klar();
– Abfrage über Conversion-Operator (→ 0, falls fail)
if (cout << x) alles_klar();
if (!cout) error("Ausgabefehler!");
T buf;
while (in_stream >> buf) out_stream << buf; // Objekte kopieren
© 2005 AG Rechnernetze
5-io.5
Ein-/Ausgabe in C++
Zeichenweise Eingabe
• Einzelnes Zeichen einlesen:
get(char&)
– Liest alle Zeichen: auch Whitespace („binäre“ Eingabe)
– Beispiel: zeichenweises Kopieren:
char c;
while (cin.get(c)) cout.put(c);
• Mehrere Zeichen einlesen:
getline (char *p, streamsize n, char ende);
// mit \0
read(char *p, streamsize n);
// ohne \0
– Beispiel: Pufferweises Kopieren:
char buf[1024];
while (cin) {
cin.read(buf, sizeof buf);
cout.write(buf, cin.gcount());
© 2005 AG Rechnernetze
5-io.6
Ein-/Ausgabe in C++
Selbstdefinierte Datentypen einlesen
void checkfor(istream& i, char c) {
char delim = 0;
i >> delim;
// Falls Fehler: c == 0
if (delim != c) {
i.putback(delim);
i.clear(ios::badbit);
// Zustand setzen
}
}
istream& operator>>(istream& i, Coordinate& co) {
checkfor(i, ’(’);
if (!i) return i;
i >> co.x;
checkfor(i, ’,’);
if (!i) return i;
i >> co.y;
checkfor(i, ’)’);
return i;
}
© 2005 AG Rechnernetze
5-io.7
Ein-/Ausgabe in C++
Manipulatoren
• Flushing
cout << "Enter your name: " << flush;
cout << "Working..." << endl;
– flush und endl sind „Manipulatoren“
– Operator << überladen für Funktionszeiger-Argument:
ostream& ostream::operator<<(ostream& (*f)(ostream&)) {
f(*this);
return *this;
}
– Implementierung von flush:
ostream& flush(ostream& i) {
i.flush();
return i;
}
© 2005 AG Rechnernetze
5-io.8
Ein-/Ausgabe in C++
Manipulatoren
• Flushing
– Implementierung von endl:
ostream& endl(ostream& i) {
i.put(’\n’);
return i.flush();
}
cout << endl
cout.operator<<(endl)
endl(cout)
cout.put(’\n’)
cout.flush()
• Weitere Manipulatoren
#include <iomanip>
cout << hex << num;
cout << setprecision(4) << angle;
cin >> noskipws >> x;
© 2005 AG Rechnernetze
5-io.9
Ein-/Ausgabe in C++
Eigene Streams erzeugen
• Filestreams
– ifstream, ofstream → abgeleitet von istream, ostream
– Bidirektional: fstream
#include <fstream>
void file_copy(char* from, char* to) {
ifstream i(from);
if (!i)
error...
ofstream o(to);
if (!o)
error...
char c;
while (i.get(c) && o) o.put(c);
if (!i.eof() || !o)
error...
}
© 2005 AG Rechnernetze
5-io.10
Ein-/Ausgabe in C++
Eigene Streams erzeugen
• Filestreams
– Explizites Öffnen und Schließen
ifstream i;
...
i.open(argv[1]);
if (!i)
error...
process_file(i);
i.close();
– Expliziten Mode angeben:
ofstream o("logfile", ios_base::out|ios_base::app);
o.open("a.out", ios_base::out|ios_base::binary
|ios_base::trunc);
– Defaults: in und out|trunc
© 2005 AG Rechnernetze
5-io.11
Ein-/Ausgabe in C++
Pufferung: Streambufs
• Jedem Stream liegt ein Streambuf zugrunde
– Unterschiedliche Streambufs für istream, ostream, fstream, stringstream...
– ostream-Memberfunktionen zum Steuern des Streambufs:
pos_type tellp ()
ostream& seekp (pos_type)
ostream& seekp (off_type, ios_base::seekdir) // beg, cur, end
ostream& flush ()
– istream-Memberfunktionen:
pos_type tellg ()
istream& seekg (pos_type)
istream& seekg (off_type, ios_base::seekdir)
istream& putback (char)
istream& unget ()
int_type peek()
© 2005 AG Rechnernetze
5-io.12