Dateineingabe und ~Ausgabe - Christian-Albrechts
Transcription
Dateineingabe und ~Ausgabe - Christian-Albrechts
Programmieren in C/C++ und MATLAB Christof Beyer Sebastian Bauer Sven Willert Sabine Schmidt Institut für Geowissenschaften Christian-Albrechts-Universität zu Kiel Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-1 Zeichenketten Bisher eingeführt war für Namen nur der Datentyp char. Dieser erlaubt das Speichern eines Buchstabens, z.B.: char n; n = ‘B‘; Soll mehr als ein Buchstabe verwendet werden, so muss man eine Zeichenkette definieren, da es keinen elementaren Datentyp für Zeichenketten gibt (gilt für C und C++): char text[21]; // Deklaration einer Zeichenkette text = “Text der Zeichenkette“; char text2[] = “Text der Zeichenkette“; // Implizite Deklaration cin >> text; // Achtung! Tastatureingabe darf nicht länger // als 21 Zeichen sein Das Problem ist wie bei den Zahlen-Feldern auch, dass die Größe fest vorgegeben werden muss. So passieren leicht Speicherfehler, die zum Programmabsturz führen können. Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-2 Strings Der Datentyp string in C++ erlaubt einen einfachen Umgang mit Zeichenketten. Diese passen sich automatisch der Länge der Zeichenkette an, somit können keine Speicherfehler mehr auftreten. Um Strings verwenden zu können, muss die Standardbibliothek eingebunden sein, und der Namenraum definiert werden: #include <cstdlib> using namespace std; string s1; // Deklaration eines strings mit Namen s1 s1 = “Text der Zeichenkette”; string s2 = “Ankuendigung”; Für Strings gibt es die Konkenation, also die Verknüpfung: s1 = s1 + s2; // Ergibt: “Text der ZeichenketteAnkuendigung” Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-3 Strings Ebenso existieren für Strings Vergleiche: if(s1 == s2) cout << “ Strings sind gleich“; Lexikographischer Vergleich mit „<„ und „<„: string s1 = “Bauer“; string s2 = “Bader“; if(s1 < s2) // Schreiben in alphabetischer Reihenfolge cout << s1 << “ “ << s2; else cout << s2 << “ “ << s1; Man kann aus einem String einen Teil herausnehmen, um nur auf diesen Teil Zugriff zu haben: string s1 = “Zeichenkette“ string s2 = s1.substr(1,5); // Kopiert ab Position 1 die folgenden // 5 Zeichen in s2 Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-4 Strings Ebenso können Teile eines Strings ersetzt werden: string s1 = “Text der Zeichenkette”; string s2 = s1.replace(9, 12, “Ankuendigung”); ersetzt ab Zeichen 9 die folgenden 12 Zeichen durch den String “Ankuendigung“. In Strings kann gesucht werden. Die Methode find(„Text“) liefert die Position des gefundenen Textes zurück (pos >= 0), bzw. -1 falls der Text nicht im String enthalten ist. int pos = s2.find(“Ank“); // liefert 9 zurueck int pos = s2.find(“Amk“); // liefert‐1 zurueck Man kann aus einem String eine char-Zeichenkette machen, da diese oft von C++ Methoden verlangt wird. Dazu verwendet man die Methode c_str(), die eine Zeichenkette für C zurückliefert. (Beispiel siehe später) Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-5 Strings Strings können anhand der Operatoren >> und << in der Ein- und Ausgabe verwendet werden: string s1; cin >> s1; // Lies string von Tastatur string s2 = “ Ihre Eingabe: “; s2 +=s1; cout << s2 << endl; Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-6 File Input Output Bisher konnten einem Programm nur Daten über die Tastatur eingegeben werden, und die Ausgabe erfolgte am Bildschirm. Dazu wurde die Standardein- und –ausgabe verwendet: #include <iostream> // Einbinden der Bibliothek für cin und cout using namespace std; // Festlegen des Namensraums int x; // Deklaration einer int‐Variable mit Namen x cin >> x; // liest eine int‐Zahl von der Tastatur cout << “ x = “ << x << endl; // Schreibt Text und eine Zahl // auf den Bildschirm Für größere Datenmengen ist dies jedoch sehr unpraktisch, und man braucht Methoden, um aus Dateien zu lesen bzw. in Dateien zu Schreiben. Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-7 File Input Output Um Dateien lesen und Schreiben zu können, muss das entsprechende Header-File <fstream> eingebunden werden: #include <fstream> // Einbinden der Bibliothek für File‐IO using namespace std; // Festlegen des Namensraums Für Dateien, aus denen gelesen wird, gibt es den Datentyp ifstream, für Dateien, in die geschrieben wird, den Dateityp ofstream. ofstream outfile; // Deklaration einer Ausgabedatei outfile.open(“ausgabe.txt“); // Oeffnet eine Ausgabedatei mit // Name ausgabe.txt outfile << “Hallo“ << endl; // Schreibt Hallo in die Datei outfile.close(); // Schliessen der Datei Mit der Methode open(“Dateiname“) kann eine Datei geöffnet werden, der Name wird dabei übergeben. Ist die Datei nicht vorhanden, so wird sie neu erzeugt. Die Methode close() schließt die Datei wieder. Der Operator << kann verwendet werden, um Text oder Zahlen in die Datei zu Schreiben. Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-8 File Input Output Manchmal muss man angeben, was man mit der Datei machen möchte. Das Betriebssystem positioniert einen sog. Dateizeiger, der auf die Stelle in der Datei zeigt, an der geschrieben bzw. gelesen wird. Ohne besondere Angaben steht der Dateizeiger am Anfang. Hat die Datei schon einen Inhalt, so wird dieser Überschrieben. ios_bas::app ios_base::ate ios_base::binary ios_base::nocreate Sebastian Bauer Institut für Geowissenschaften Datei Datei Datei Datei wird wird wird wird geöffnet, neue Daten hinten angehängt geöffnet, Dateizeiger zeigt auf das Ende im Binärmodus geöffnet nicht bei Bedarf neu erzeugt Programmieren in C/C++ und MATLAB CAU 7-9 File Input Output Beim Umgang mit Dateien ist große Sorgfalt geboten. Daher sollten unbedingt Fehlerabfragen verwendet werden, falls z.B. die zu öffnende Datei nicht vorhanden ist oder der Zugriff nicht funktioniert (Datei mit anderem Programm geöffnet). Dazu liefern ifstream oder ofstream 0 zurück, falls ein Fehler aufgetreten ist: ifstream infile; infile.open(“eingabe.txt“); if(!infile) cout << “Fehler beim Oeffnen der Datei eingabe.txt“; Aus der Datei kann gelesen werden mit >>. Dabei werden jeweils die nächsten Daten ausgelesen und in eine Variable gespeichert. Die Variable muss zum Datentyp, der tatsächlich gelesen wird, passen! (Sonst: Implizite Typumwandlung). double x, y, z; int wert; infile >> x >> y >> z >> wert; Liest einen int-Wert für einen Punkt in 3D ein. Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-10 File Input Output Ausgabeformatierung Auffüllen auf vorgegebene Breite: Mit Hilfe von width() kann die Breite der unmittelbar folgenden Ausgabe eingestellt werden. Liefert die Ausgabe weniger Zeichen, als durch width() festgelegt, wird mit Leerzeichen aufgefüllt. Soll ein anderes Füllzeichen verwendet werden, kann dieses mit fill() gesetzt werden. cout << 1 << “ und “ << 1 << endl; // Ausgabe: 1 und 1 cout.width(5); // Setzen der Audgabebreite auf 5 Zeichen cout.fill(‘‐‘); // Fuellzeichen ist nun – statt Leerzeichen cout << 1 << “ und “ << 1 << endl; // Ausgabe: ‐‐‐‐1 und 1 Die Festlegung der Breite gilt nur für die nächste Ausgabe (<< Zeichen, siehe oben). Alternativ kann das auch als sog. Manipulator gesetzt werden: cout << setw(5) << setfill(‚‘‐‘) << 1 << “ und “ << 1 << endl; Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-11 File Input Output Ausgabeformatierung Genauigkeit Die Anzahl der Ziffern von Gleitkommazahlen wird anhand von precision() gesteuert. Diese Festlegung gilt dauerhaft, kann aber durch erneuten Aufruf von precision() geändert werden. Enthält die interne Darstellung mehr Ziffern, so wird gerundet. cout.precision(6); cout << 1234.56789 << endl; // Ausgabe: 1234.57 Oft wird in der Wissenschaft das Ergebnis als Exponentialzahl angegeben (x*10n oder xe+n). Dazu wird das flag ios_base::scientific gesetzt, und mit precision() die Anzahl der Nachkommastellen festgelegt cout.setf(ios_base::scientific); cout.precision(4); cout << 1234.56789012345 << endl; //Ausgabe: 1.2346e+03 Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-12 Übung Matrizen Schreiben Sie das Matrizenprogramm von letzter Woche so um, dass Sie sowohl die Dimension der Matrizen als auch die Matrizen a und b aus einer Datei einlesen können. Der Dateiname dieser Eingabedatei soll über die Bildschirmeingabe eingelesen werden können, ebenso soll der Name der Ausgabedatei über die Tastatur eingegeben werden können. In diese Ausgabedatei soll die Matrix c geschrieben werden, also das Ergebnis der Addition oder Multiplikation. Die Eingabedatei finden Sie auf der Homepage als *.txt und gezipped. Ebenso ist dort eine Version des Programms von letzter Woche, das Sie als Startprogramm verwenden können, wenn Sie letzte Woche nicht fertig geworden sind. Verwenden Sie das Programm aus der letzten Stunde, kopieren Sie es jedoch vorher unbedingt! in ein neues Unterverzeichnis. Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-13 Übung Hinweise: Für die Eingabedatei kann nun der Name nicht mehr als feste charZeichenkette vorgegeben werden, sondern dieser wird von der Tastatur gelesen. Dabei muss der string noch in eine c-Zeichenkette umgewandelt werden anhand von c_str(): string name_in; ifstream infile; ... cin >> name_in; ... infile.open(name_in.c_str()); if(!infile) ... ... Sebastian Bauer Institut für Geowissenschaften Programmieren in C/C++ und MATLAB CAU 7-14