User Tools

Site Tools


cpp:stream_states

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

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

flag Περιγραφή
goodbit Κανένα λάθος. Το stream δουλεύει σωστά.
badbit Έχει συμβεί ένα κρίσιμο λάθος από τον οποίο δεν μπορεί να ανακάμψει το stream.
eofbit Έχουμε φτάσει κατά την ανάγνωση στο τέλος του stream
failbit Το flag τίθεται όταν συμβεί οποιοδήποτε λάθος από το οποίο μπορεί ή δεν μπορεί να ανακάμψει το stream. To flag τίθεται πάντα όταν έχει τεθεί και το flag badbit. Επιπλέον, μπορεί να τεθεί εάν συμβεί ένα μη κρίσιμο λάθος. Για παράδειγμα, έχουμε αποτύχει να διαβάσουμε αυτό που υποδεικνύει ο κώδικας, αλλά μπορούμε να συνεχίσουμε την ανάγνωση (π.χ. επιχειρούμε το διάβασμα ενός αριθμού κινητής υποδιαστολής, όμως ως είσοδος παρέχεται μία ακολουθία γραμμάτων).

Οι ακόλουθες μέθοδοι ενημερώνουν για την εσωτερική κατάσταση του 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 είναι πιθανό ότι μπορεί να χρησιμοποιηθεί για επιπλέον λειτουργίες εισόδου ή εξόδου.

Εναλλακτικά, μπορείτε να διαβάσετε το σύνολο των παραπάνω τιμών χρησιμοποιώντας τη συνάρτηση std::ios::rdstate(). Σε αυτή την περίπτωση όμως θα πρέπει να ξεχωρίσετε ποια flags είναι ενεργά και ποια όχι. Το ακόλουθο παράδειγμα είναι ενδεικτικό για το πως μπορείτε να χρησιμοποιήσετε τα flags για να ελέγξετε εάν ένα αρχείο έχει ανοίξει σωστά ή όχι, ελέγχοντας την κατάσταση του stream που το συνοδεύει.

check_file_open.cpp
#include <iostream>
#include <fstream>
 
using namespace std;
 
int main () {
  std::ifstream fs;
  fs.open("non-exist.txt");
  if ( (fs.rdstate() & std::fstream::failbit ) != 0 )
    std::cerr << "Error opening file 'non-exist.txt'\n";
}

Έλεγχος των τιμών εισόδου (input validation)

Με έλεγχο των παραπάνω flags μπορούμε να κάνουμε έλεγχο της εισόδου που εισάγει ο χρήστης σε ένα πρόγραμμα, όταν καλούμαστε να διαβάσουμε έναν ακέραιο ή αριθμό κινητής υποδιαστολής. Δείτε το παρακάτω παράδειγμα, όπου ο χρήστης καλείται να εισάγει το βάρος του ως θετικό αριθμό κινητής υποδιαστολής. Εάν εισάγει κάτι διαφορετικό το πρόγραμμα ελέγχει το failbit και εφόσον αυτό είναι ενεργό, επαναλαμβάνει τη διαδικασία. Η συνάρτηση ignore αγνοεί τόσους χαρακτήρες όσους προσδιορίζει η 1η παράμετρος ή εάν βρεθεί ο χαρακτήρας που προσδιορίζεται στη 2η παράμετρο (όποιο από τα δύο συμβεί 1ο).

input_validation.cpp
#include <iostream>
#include <fstream>
 
using namespace std;
 
int main() {
  double weight;
 
  while (true) {
    cout << "Enter your weight: ";
    cin >> weight;
 
    if (cin.fail()) {
      // We failed to extract a double
      cin.clear();           // reset stream state to goodbit.
      cin.ignore(256, '\n'); // remove any input from the stream until \n
      continue;
    }
 
    if (weight <= 0)
      continue;
 
    break;
  }
 
  cout << "You weight is: " << weight << endl;
}
cpp/stream_states.txt · Last modified: 2021/06/01 06:55 (external edit)