User Tools

Site Tools


cpp:stream_states

This is an old revision of the document!


Έλεγχος της εσωτερικής κατάστασης του stream

Κάθε stream διαθέτει μία σειρά από flags που ενημερώνουν για την κατάσταση του. Τα flags αυτά αποθηκεύονται στην μεταβλητή std::iosbase::iostate. Συγκεκριμένα η μεταβλητή περιέχει τα παρακάτω flags.

flag Περιγραφή
eofbit End-Of-File reached while performing an extracting operation on an input stream.
failbit The last input operation failed because of an error related to the internal logic of the operation itself.
badbit Error due to the failure of an input/output operation on the stream buffer.
goodbit No error. Represents the absence of all the above (the value zero).

Οι ακόλουθες μέθοδοι ενημερώνουν για την εσωτερική κατάσταση του stream επιστρέφοντας μία boolean τιμή ως εξής:

bool good() const;
Επιστρέφει true εάν κανένα από τα error flags (failbit, badbit, eofbit) δεν έχει τιμή true.
bool bad() const;
Ελέγχει εάν το badbit είναι true. Το badbit λαμβάνει τη τιμή true εάν συμβεί κάποιο μη αναστρέψιμο σφάλμα στο εσωτερικό του stream. Εάν το badbit γίνει true οποιαδήποτε ενέργεια πάνω στο stream θα πρέπει να αποκλειστεί.
bool eof() const;
Ελέγχει εάν το eofdbit είναι true. To eofbit γίνεται true, όταν η διαδικασία ανάγνωσης φτάνει στο τέλος του αρχείου.
bool fail() const;
Ελέγχει εάν το failbit ή το badbit έχουν τιμή true. Το failbit λαμβάνει τη τιμή true εάν συμβεί κάποιο λάθος στη χρήση του stream. Το λάθος δεν θεωρείται μη αναστρέψιμο και το stream είναι πιθανό ότι μπορεί να χρησιμοποιηθεί για επιπλέον λειτουργίες εισόδου ή εξόδου.

Αλλαγή της θέσης ανάγνωσης ή εγγραφής στο stream

Τα streams εισόδου διατηρούν τη θέση ανάγνωσης και τα streams εξόδου τη θέση εγγραφής. Streams που υποστηρίζουν είσοδο και έξοδο διατηρούν ξεχωριστές θέσεις για ανάγνωση και για εγγραφή.

Ανάγνωση της θέσης ανάγνωσης ή εγγραφής

Η κλάση istream διαθέτει τη συνάρτηση tellg για την ανάγνωση της θέσης ανάγνωσης μέσα στο stream. Η συνάρτηση επιστρέφει ένα αντικείμενο του τύπου streampos και ορίζεται ως εξής:

streampos tellg();

Η κλάση ostream διαθέτει τη συνάρτηση tellp για την ανάγνωση της θέσης εγγραφής μέσα στο stream. Η συνάρτηση επιστρέφει ένα αντικείμενο του τύπου streampos και ορίζεται ως εξής:

streampos tellp();

Αλλαγή της θέσης ανάγνωσης ή εγγραφής

Η κλάση istream διαθέτει τη συνάρτηση seekg για την αλλαγή της θέσης ανάγνωσης μέσα στο stream. Η συνάρτηση επιστρέφει μία αναφορά στο υφιστάμενο stream και ορίζεται ως εξής:

istream& seekg (streampos pos);
istream& seekg (streamoff off, ios_base::seekdir way);

Η κλάση ostream διαθέτει τη συνάρτηση seekp για την αλλαγή της θέσης εγγραφής μέσα στο stream. Η συνάρτηση επιστρέφει μία αναφορά στο υφιστάμενο stream και ορίζεται ως εξής:

ostream& seekp (streampos pos);
ostream& seekp (streamoff off, ios_base::seekdir way);

Οι παράμετροι που λαμβάνουν οι συναρτήσεις seekg και seekp είναι οι εξής:

  • pos: Απόλυτη θέση μέσα στο stream ξεκινώντας από την αρχή.
  • off: Σχετική θέση μέσα στο stream. Συνδέεται με την τιμή της μεταβλητής way.
  • way: Μπορεί να πάρει μία από τις παρακάτω τιμές
ios::beg αρχή του stream
ios::cur τρέχουσα θέση του stream
ios::end τέλος του stream

Ακολουθούν δύο παραδείγματα αλλαγής της θέσης ανάγωσης και εγγραφής πάνω στο file stream.

fileseek.cpp
#include <iostream>
#include <fstream>
using namespace std;
 
int main (int argc, char *argv[]) {  
  string filename;
  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;    
  }
  outfile << "I hate pointers   in C";
  outfile.flush();
 
  ifstream infile(filename.c_str());
  if (!infile.is_open()) {
    cout << "[Read] Unable to open " << filename;
    return -1;    
  }
  string line;
  getline( infile, line );
  cout << line << endl;  
 
  outfile.seekp(2);
  outfile << "love";
  outfile.seekp(1, ios::cur);
  outfile << "references";
  outfile.seekp(0,ios::end);
  outfile << "++" << endl;
 
  infile.seekg(0, ios::beg);
  getline( infile, line );
  cout << line << endl;  
}
filesize.cpp
#include <iostream>
#include <fstream>
using namespace std;
 
int main () {
  streampos begin,end;
  string filename;
  cout << "Enter filename: ";
  cin >> filename;
  ifstream file(filename.c_str());
  if (!file.is_open()) {
    cout << "Unable to open " << filename;
    return -1;    
  }
  begin = file.tellg();
  file.seekg (0, ios::end);
  end = file.tellg();
  myfile.close();
  cout << "file size is: " << (end-begin) << " bytes.\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.

binary_copy.cpp
#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();
}
cpp/stream_states.1558352641.txt.gz · Last modified: 2019/05/20 10:44 (external edit)