User Tools

Site Tools


cpp:stream_states

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
cpp:stream_states [2019/05/20 11:44] – created gthanoscpp:stream_states [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
Line 1: Line 1:
-===== Έλεγχος της εσωτερικής κατάστασης του stream =====+====== Έλεγχος της εσωτερικής κατάστασης του stream ======
  
 Κάθε //stream// διαθέτει μία σειρά από //flags// που ενημερώνουν για την κατάσταση του. Τα //flags// αυτά αποθηκεύονται στην μεταβλητή //[[http://www.cplusplus.com/reference/ios/ios_base/iostate/|std::iosbase::iostate]]//. Συγκεκριμένα η μεταβλητή περιέχει τα παρακάτω //flags//. Κάθε //stream// διαθέτει μία σειρά από //flags// που ενημερώνουν για την κατάσταση του. Τα //flags// αυτά αποθηκεύονται στην μεταβλητή //[[http://www.cplusplus.com/reference/ios/ios_base/iostate/|std::iosbase::iostate]]//. Συγκεκριμένα η μεταβλητή περιέχει τα παρακάτω //flags//.
  
 ^  flag  ^  Περιγραφή  ^ ^  flag  ^  Περιγραφή  ^
-|  **eofbit**  | End-Of-File reached while performing an extracting operation on an input stream. | +|  **goodbit**  | Κανένα λάθος. Το //stream// δουλεύει σωστά. | 
-|  **failbit**  | The last input operation failed because of an error related to the internal logic of the operation itself. | +|  **badbit**  | Έχει συμβεί ένα κρίσιμο λάθος από τον οποίο δεν μπορεί να ανακάμψει το //stream// 
-|  **badbit**  | Error due to the failure of an input/output operation on the stream buffer. +|  **eofbit**  | Έχουμε φτάσει κατά την ανάγνωση στο τέλος του //stream// 
-|  **goodbit**  | No errorRepresents the absence of all the above (the value zero). |+|  **failbit**  | Το flag τίθεται όταν συμβεί οποιοδήποτε λάθος από το οποίο μπορεί ή δεν μπορεί να ανακάμψει το streamTo flag τίθεται πάντα όταν έχει τεθεί και το flag **badbit**. Επιπλέον, μπορεί να τεθεί εάν συμβεί ένα __μη κρίσιμο__ λάθος. Για παράδειγμα, έχουμε αποτύχει να διαβάσουμε αυτό που υποδεικνύει ο κώδικας, αλλά μπορούμε να συνεχίσουμε την ανάγνωση (π.χ. επιχειρούμε το διάβασμα ενός αριθμού κινητής υποδιαστολής, όμως ως είσοδος παρέχεται μία ακολουθία γραμμάτων). |
  
 Οι ακόλουθες μέθοδοι ενημερώνουν για την εσωτερική κατάσταση του //stream// επιστρέφοντας μία //boolean// τιμή ως εξής: Οι ακόλουθες μέθοδοι ενημερώνουν για την εσωτερική κατάσταση του //stream// επιστρέφοντας μία //boolean// τιμή ως εξής:
Line 15: Line 15:
 |  <code cpp>bool fail() const;</code>  | Ελέγχει εάν το **failbit** ή το **badbit** έχουν τιμή //true//. Το **failbit** λαμβάνει τη τιμή //true// εάν συμβεί κάποιο λάθος στη χρήση του //stream//. Το λάθος δεν θεωρείται μη αναστρέψιμο και το //stream// είναι πιθανό ότι μπορεί να χρησιμοποιηθεί για επιπλέον λειτουργίες εισόδου ή εξόδου. | |  <code cpp>bool fail() const;</code>  | Ελέγχει εάν το **failbit** ή το **badbit** έχουν τιμή //true//. Το **failbit** λαμβάνει τη τιμή //true// εάν συμβεί κάποιο λάθος στη χρήση του //stream//. Το λάθος δεν θεωρείται μη αναστρέψιμο και το //stream// είναι πιθανό ότι μπορεί να χρησιμοποιηθεί για επιπλέον λειτουργίες εισόδου ή εξόδου. |
  
-===== Αλλαγή της θέσης ανάγνωσης ή εγγραφής στο stream =====+Εναλλακτικά, μπορείτε να διαβάσετε το σύνολο των παραπάνω τιμών χρησιμοποιώντας τη συνάρτηση [[http://www.cplusplus.com/reference/ios/ios/rdstate/|std::ios::rdstate()]]. Σε αυτή την περίπτωση όμως θα πρέπει να ξεχωρίσετε ποια //flags// είναι ενεργά και ποια όχι. Το ακόλουθο παράδειγμα είναι ενδεικτικό για το πως μπορείτε να χρησιμοποιήσετε τα //flags// για να ελέγξετε εάν ένα αρχείο έχει ανοίξει σωστά ή όχι, ελέγχοντας την κατάσταση του //stream// που το συνοδεύει.
  
-Τα //streams// εισόδου διατηρούν τη θέση ανάγνωσης και τα //streams// εξόδου τη θέση εγγραφής. //Streams// που υποστηρίζουν είσοδο και έξοδο διατηρούν ξεχωριστές θέσεις για ανάγνωση και για εγγραφή.  +<code cpp check_file_open.cpp>
- +
-=== Ανάγνωση της θέσης ανάγνωσης ή εγγραφής === +
- +
-Η κλάση //istream// διαθέτει τη συνάρτηση //tellg// για την ανάγνωση της θέσης ανάγνωσης μέσα στο //stream//. Η συνάρτηση επιστρέφει ένα αντικείμενο του τύπου //streampos// και ορίζεται ως εξής: +
-<code cpp>streampos tellg();</code> +
- +
-Η κλάση //ostream// διαθέτει τη συνάρτηση //tellp// για την ανάγνωση της θέσης εγγραφής μέσα στο //stream//. Η συνάρτηση επιστρέφει ένα αντικείμενο του τύπου //streampos// και ορίζεται ως εξής: +
-<code cpp>streampos tellp();</code> +
- +
-=== Αλλαγή της θέσης ανάγνωσης ή εγγραφής === +
- +
-Η κλάση //istream// διαθέτει τη συνάρτηση //seekg// για την αλλαγή της θέσης ανάγνωσης μέσα στο //stream//. Η συνάρτηση επιστρέφει μία αναφορά στο υφιστάμενο //stream// και ορίζεται ως εξής: +
-<code cpp>istream& seekg (streampos pos); +
-istream& seekg (streamoff off, ios_base::seekdir way);</code> +
- +
-Η κλάση //ostream// διαθέτει τη συνάρτηση //seekp// για την αλλαγή της θέσης εγγραφής μέσα στο //stream//. Η συνάρτηση επιστρέφει μία αναφορά στο υφιστάμενο //stream// και ορίζεται ως εξής: +
-<code cpp>ostream& seekp (streampos pos); +
-ostream& seekp (streamoff off, ios_base::seekdir way);</code> +
- +
-Οι παράμετροι που λαμβάνουν οι συναρτήσεις //seekg// και //seekp// είναι οι εξής: +
-  * **pos:** Απόλυτη θέση μέσα στο //stream// ξεκινώντας από την αρχή. +
-  * **off:** Σχετική θέση μέσα στο //stream//. Συνδέεται με την τιμή της μεταβλητής **way**. +
-  * **way:** Μπορεί να πάρει μία από τις παρακάτω τιμές +
- +
-|  **ios::beg**  | αρχή του //stream// | +
-|  **ios::cur**  | τρέχουσα θέση του //stream// | +
-|  **ios::end**  | τέλος του //stream// | +
- +
-Ακολουθούν δύο παραδείγματα αλλαγής της θέσης ανάγωσης και εγγραφής πάνω στο //file stream//.  +
- +
-<code cpp fileseek.cpp>+
 #include <iostream> #include <iostream>
 #include <fstream> #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;   
-}</code> 
  
-<code cpp filesize.cpp> 
-#include <iostream> 
-#include <fstream> 
 using namespace std; using namespace std;
  
 int main () { int main () {
-  streampos begin,end; +  std::ifstream fs
-  string filename; +  fs.open("non-exist.txt"); 
-  cout << "Enter filename"+  if ( (fs.rdstate() & std::fstream::failbit !
-  cin >> filename; +    std::cerr << "Error opening file 'non-exist.txt'\n";
-  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";+
 } }
 </code> </code>
  
-===== Δυαδικά αρχεία =====+===== Έλεγχος των τιμών εισόδου (input validation) =====
  
-Για δυαδικά αρχεία η ανάγνωση και η εγγραφή με χρήση των τελεστών %%<<%% (//extraction operator//και %%>>%% (//insertion operator//δεν είναι εφικτή. Για τον λόγο αυτό τα //file streams// περιέχουν δύο μεθόδους για διάβασμα και γράψιμο δυαδικής πληροφορίας.+Με έλεγχο των παραπάνω //flags// μπορούμε να κάνουμε έλεγχο της εισόδου που εισάγει ο χρήστης σε ένα πρόγραμμα, όταν καλούμαστε να διαβάσουμε έναν ακέραιο ή αριθμό κινητής υποδιαστολής. Δείτε το παρακάτω παράδειγμα, όπου ο χρήστης καλείται να εισάγει το βάρος του ως θετικό αριθμό κινητής υποδιαστολής. Εάν εισάγει κάτι διαφορετικό το πρόγραμμα ελέγχει το //failbit// και εφόσον αυτό είναι ενεργό, επαναλαμβάνει τη διαδικασία. Η συνάρτηση [[http://www.cplusplus.com/reference/istream/istream/ignore/|ignore]] αγνοεί τόσους χαρακτήρες όσους προσδιορίζει η 1η παράμετρος ή εάν βρεθεί ο χαρακτήρας που προσδιορίζεται στη 2η παράμετρο (όποιο από τα δύο συμβεί 1ο)
  
-|  <code cpp>istream& read (char* s, streamsize n);</code>  | Διάβασμα //n// στοιχείων τύπου //char// από το //stream// και αποθήκευση στο //s//. Η συνάρτηση επιστρέφει μία αναφορά στο υφιστάμενο stream. Σε περίπτωση που δεν υπάρχουν //n// διαθέσιμα bytes στο //stream// αντιγράφει στο //s// όσα είναι διαθέσιμα και θέτει τα //flags// **failbit** και **eofbit**. Ο αριθμός των bytes που διαβάστηκαν επιστρέφεται από τη συνάρτηση [[http://www.cplusplus.com/reference/istream/istream/gcount/|gcount]]. +<code cpp input_validation.cpp>
-|  <code cpp>ostream& write (const char* s, streamsize n);</code>  | Γράψιμο //n// στοιχείων τύπου //char// από το //s// προς το //stream//. | +
- +
-Δείτε το παρακάτω παράδειγμα ανάγνωσης και εγγραφής από δυαδικό αρχείο. Το πρόγραμμα αντιγράφει το περιεχόμενο ενός υφιστάμενου αρχείου σε ένα άλλο σε τμήματα των SIZE bytes. +
- +
-<code cpp binary_copy.cpp>+
 #include <iostream> #include <iostream>
 #include <fstream> #include <fstream>
-#include <cmath>+
 using namespace std; using namespace std;
  
-#define SIZE 512+int main() { 
 +  double weight;
    
-int main (int argc, char *argv[]) {   +  while (true) { 
-  string filename; +    cout << "Enter your weight: "; 
-  cout << "Enter input filename: "; +    cin >> weight
-  cin >> filename+  
-  ifstream infile(filename.c_str()); +    if (cin.fail()) { 
-  if (!infile.is_open()) { +      // We failed to extract a double 
-    cout << "[Read] Unable to open " << filename+      cin.clear();           // reset stream state to goodbit. 
-    return -1   +      cin.ignore(256, '\n'); // remove any input from the stream until \n 
 +      continue; 
 +    
 +  
 +    if (weight <= 0) 
 +      continue; 
 +  
 +    break;
   }   }
-   +  
-  cout << "Enter output filename: "+  cout << "You weight is: " << weight << endl;
-  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();+
 } }
 </code> </code>
 +
  
cpp/stream_states.1558352641.txt.gz · Last modified: 2019/05/20 10:44 (external edit)