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