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