Η standard βιβλιοθήκη της C++ παρέχει τις παρακάτω κλάσεις για είσοδο και έξοδο από αρχεία.
Οι παραπάνω κλάσεις είναι απόγονοι των κλάσεων istream και ostream. Η χρήση των παραπάνω κλάσεων είναι ανάλογη με τις κλάσεις std::cin και std::cout που επίσης είναι απόγονοι των κλάσεων istream και ostream. Δείτε ενδεικτικά, το παρακάτω παράδειγμα γραφής στο αρχείο hello.txt.
#include <iostream> #include <fstream> using namespace std; int main() { ofstream myfile; myfile.open ("hello.txt"); myfile << "Hello World!"; myfile.close(); }
Το άνοιγμα των αρχείων γίνεται μέσω της μεθόδου open η οποία προδιαγράφεται παρακάτω:
void open (const char* filename, ios_base::openmode mode);
Η παράμετρος filename είναι ένα αλφαριθμητικό που περιγράφει το σχετικό ή απόλυτο path προς το αρχείο. Η παράμετρος mode μπορεί να πάρει τις ακόλουθες τιμές ή συνδυασμούς τους:
Τιμή | Επεξήγηση |
---|---|
ios::in | Άνοιγμα για ανάγνωση από το αρχείο. |
ios::out | Άνοιγμα για εγγραφή στο αρχείο. |
ios::binary | Άνοιγμα για ανάγνωση ή εγγραφή σε δυαδική μορφή. |
ios::app | Η θέση εγγραφής τίθεται στο τέλος του αρχείου. Εάν επιχειρήσετε να μεταβάλλετε τη θέση εγγραφής μέσω της συνάρτησης seekp αυτό δεν θα έχει αποτέλεσμα. |
ios::ate | Θέτει τη θέση εγγραφής στο τέλος του αρχείου. Εάν δεν προσδιοριστεί το συγκεκριμένο flag η θέση εγγραφής τίθεται στην αρχή. Μπορείτε να μεταβάλλετε τη θέση εγγραφής μέσω της συνάρτησης seekp |
ios::trunc | Εάν το αρχείο υπάρχει ήδη και έχει περιεχόμενο, το υφιστάμενο περιεχόμενο διαγράφεται. |
Οι παραπάνω τιμές μπορούν να συνδυαστούν ως εξής:
ofstream lena; // Open lena.png for writing in binary mode. // Truncate file contents if file previously exists. lena.open("lena.png", ios::out | ios::trunc | ios::binary);
Οι default τιμές της παραμέτρου mode για τις παραπάνω κλάσεις κλάσεις έχουν ως εξής:
Κλάση | Τιμή | Παρατήρηση |
---|---|---|
ofstream | ios::out | Η τιμή ισχύει ακόμη και εάν αλλάξετε την παράμετρο mode |
ifstream | ios::in | Η τιμή ισχύει ακόμη και εάν αλλάξετε την παράμετρο mode |
fstream | ios::in | ios::out | Η τιμή δεν ισχύει εάν αλλάξετε την παράμετρο mode. Μπορείτε να επαναορίσετε τις τιμές |
Παρατηρήστε ότι η μέθοδος open δεν έχει επιστρεφόμενη τιμή για να ελέγξουμε την αποτυχία, ούτε παράγει κάποιο exception. Για να ελέγξετε εάν ένα αρχείο έχει ανοίξει σωστά για διάβασμα ή γράψιμο μπορείτε να χρησιμοποιήσετε τη μέθοδο is_open() ως εξής:
ofstream lena("lena.png", ios::out | ios::trunc | ios::binary); if (!lena.is_open()) { cerr << "Error while opening \"lena.png\" for writting\n"; }
Παρατηρήστε ότι στο παραπάνω παράδειγμα χρησιμοποιούμε τον κατασκευαστή της κλάσης ofstream αντί για τη μέθοδο open. Τα ορίσματα που λαμβάνει ο κατασκευαστής και η σειρά τους είναι ταυτόσημα με αυτά της μεθόδου open.
Για να κλείσετε το αρχείο που προηγουμένως ανοίξατε με τη μέθοδο open αρκεί να καλέσετε τη μέθοδο close ως εξής:
lena.close();
Streams κειμένου είναι εκείνα τα streams που κατά το άνοιγμα του αρχείου δεν έχουν ορισμένο το flag ios::binary. Τα αρχεία αυτά υποθέτουμε ότι περιέχουν μόνο εκτυπώσιμους χαρακτήρες (δηλ. κείμενο) και κατ' επέκταση μπορούμε να τα διαβάσουμε υποθέτοντας ότι οι λέξεις χωρίζονται μεταξύ τους από κενό χαρακτήρα ή χαρακτήρα αλλαγής γραμμής (' ','\t','\n','\x0B','\f','\r
') και οι γραμμές χωρίζονται με χαρακτήρα αλλαγής γραμμής ('\r','\n
').
Ο τρόπος με τον οποίο γράφετε ή διαβάζετε είναι ο τρόπος που το κάνετε για τη βασική είσοδο και έξοδο.
Γράψιμο σε αρχείο κειμένου |
---|
|
Διάβασμα από αρχείο κειμένου γραμμή-γραμμή | Διάβασμα από αρχείο κειμένου λέξη-λέξη και εκτύπωση κάθε λέξης σε νέα γραμμή |
---|---|
|
|
Για δυαδικά αρχεία η ανάγνωση και η εγγραφή με χρήση των τελεστών << (extraction operator) και >> (insertion operator) δεν είναι εφικτή. Για τον λόγο αυτό τα file streams περιέχουν δύο μεθόδους για διάβασμα και γράψιμο δυαδικής πληροφορίας.
istream& read (char* s, streamsize n); | Διάβασμα n στοιχείων τύπου char από το stream και αποθήκευση στο s. Η συνάρτηση επιστρέφει μία αναφορά στο υφιστάμενο stream. Σε περίπτωση που δεν υπάρχουν n διαθέσιμα bytes στο stream αντιγράφει στο s όσα είναι διαθέσιμα και θέτει τα flags failbit και eofbit. Ο αριθμός των bytes που διαβάστηκαν επιστρέφεται από τη συνάρτηση gcount. |
ostream& write (const char* s, streamsize n); | Γράψιμο n στοιχείων τύπου char από το s προς το stream. |
Δείτε το παρακάτω παράδειγμα ανάγνωσης και εγγραφής από δυαδικό αρχείο. Το πρόγραμμα αντιγράφει το περιεχόμενο ενός υφιστάμενου αρχείου σε ένα άλλο σε τμήματα των SIZE bytes.
#include <iostream> #include <fstream> #include <cmath> using namespace std; #define SIZE 512 int main (int argc, char *argv[]) { string filename; cout << "Enter input filename: "; cin >> filename; ifstream infile(filename.c_str()); if (!infile.is_open()) { cout << "[Read] Unable to open " << filename; return -1; } cout << "Enter output filename: "; cin >> filename; ofstream outfile(filename.c_str(), ios::trunc); if (!outfile.is_open()) { cout << "[Write] Unable to open " << filename; return -1; } char buf[SIZE]; while(!infile.eof()) { infile.read(buf, SIZE); outfile.write(buf, infile.gcount()); } infile.close(); outfile.close(); }