====== Έλεγχος της εσωτερικής κατάστασης του stream ======
Κάθε //stream// διαθέτει μία σειρά από //flags// που ενημερώνουν για την κατάσταση του. Τα //flags// αυτά αποθηκεύονται στην μεταβλητή //[[http://www.cplusplus.com/reference/ios/ios_base/iostate/|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// (f**ailbit, 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// είναι πιθανό ότι μπορεί να χρησιμοποιηθεί για επιπλέον λειτουργίες εισόδου ή εξόδου. |
Εναλλακτικά, μπορείτε να διαβάσετε το σύνολο των παραπάνω τιμών χρησιμοποιώντας τη συνάρτηση [[http://www.cplusplus.com/reference/ios/ios/rdstate/|std::ios::rdstate()]]. Σε αυτή την περίπτωση όμως θα πρέπει να ξεχωρίσετε ποια //flags// είναι ενεργά και ποια όχι. Το ακόλουθο παράδειγμα είναι ενδεικτικό για το πως μπορείτε να χρησιμοποιήσετε τα //flags// για να ελέγξετε εάν ένα αρχείο έχει ανοίξει σωστά ή όχι, ελέγχοντας την κατάσταση του //stream// που το συνοδεύει.
#include
#include
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// και εφόσον αυτό είναι ενεργό, επαναλαμβάνει τη διαδικασία. Η συνάρτηση [[http://www.cplusplus.com/reference/istream/istream/ignore/|ignore]] αγνοεί τόσους χαρακτήρες όσους προσδιορίζει η 1η παράμετρος ή εάν βρεθεί ο χαρακτήρας που προσδιορίζεται στη 2η παράμετρο (όποιο από τα δύο συμβεί 1ο).
#include
#include
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;
}