====== Output Streams ====== Όπως προαναφέρθηκε τα //streams// εξόδου χρησιμοποιούν τον τελεστη ''<<'' (//stream insertion operator//) για εγγραφή στο //stream//. Σε αναλογία με τα //input streams//, η //standard// βιβλιοθήκη παρέχει συναρτήσεις υπεφόρτωσης για τους βασικούς τύπους δεδομένων, ενώ δίνεται η δυνατότητα [[cpp:vector_overloading_binary_operators|υπερφόρτωσης]] για όλους τους μη βασικούς τύπους που θα χρειαστεί να κατασκευάσετε στα προγράμματα σας. Το παρακάτω παράδειγμα γραψίματος στην κονσόλα (//stdout//) είναι ενδεικτικό. #include using namespace std; int main() { string str("Welcome C++"); const double PI = 3.14159; const int SIZE = 256; cout << str << " in CE325 course." << endl; cout << "Constant PI: " << PI << endl; cout << "SIZE is: " << SIZE << endl; } ====== Μεταβολή της μορφοποίησης σε ένα stream ====== Μπορείτε να αλλάξετε τη μορφοποίηση σε ένα stream με τους εξής δύο τρόπους: * χρησιμοποιώντας τις συναρτήσεις μορφοποίησης **[[http://www.cplusplus.com/reference/ios/ios_base/setf/|setf]]** (ενεργοποιεί ένα //flag// που συνδέεται με μία επιλογή μορφοποίησης) και **[[http://www.cplusplus.com/reference/ios/ios_base/unsetf/|unsetf]]** (απενεργοποιεί ένα //flag// που συνδέεται με μία επιλογή μορφοποίησης). * χρησιμοποιώντας μορφοποιητές (//manipulators//) πάνω στο //stream//. ===== Χρήση συναρτήσεων μορφοποίησης ===== Ας υποθέσουμε ότι σε ένα //stream// θέλουμε η αριθμοί να εκτυπώνονται σε δεκαεξαδική μορφή. Προκειμένου να το πετύχουμε αυτό, θα πρέπει να κάνουμε τα εξής: #include using namespace std; int main() { cout.setf(std::ios::hex); //cout.unsetf(std::ios::dec); cout << 16 << endl; } O παραπάνω κώδικας δεν δουλεύει σωστά, διότι είναι απαραίτητη και η γραμμή που είναι σε σχόλια. Στην πράξη, θα πρέπει εκτός από το να θέσουμε το //flag// ''std::ios::hex'' να καθαρίσουμε και το //flag// ''std::ios::dec''. Ο λόγος είναι ότι το //flag// ''std::ios::dec'' έχει μεγαλύτερη προτεραιότητα, και όσο είναι ενεργό οι αριθμοί εξακολουθούν να εκτυπώνονται σε δεκαδική μορφή. Εναλλακτικά, μπορείτε να χρησιμοποιήσετε την παρακάτω μορφή της συνάρτησης **setf**. #include using namespace std; int main() { cout.setf(std::ios::hex, std::ios::basefield); cout << "0x" <<16 << endl; } Η συγκεκριμένη μορφή της **set**, στην 1η παράμετρο λαμβάνει τα //flags// που θα ενεργοποιηθούν (εάν υπάρχουν περισσότερα του ενός, χρησιμοποιείτε τον δυαδικό τελεστή OR (|)) και στην 2η παράμετρο λαμβάνει το //group// των //flags// τα οποία θα μηδενιστούν, πριν ενεργοποιηθούν τα //flags// που ορίζονται στην 1η παράμετρο. ===== Χρήση μορφοποιητών (manipulators) ===== Η C++ δίνει τη δυνατότητα χρήσης μορφοποιητών, οι οποίοι επιτυγχάνουν το ίδιο ακριβώς αποτέλεσμα με τις συναρτήσεις **setf** και **unsetf** και χρησιμοποιούνται ευρέως. Για παράδειγμα το προηγούμενο πρόγραμμα μπορεί να γραφεί με χρήση μορφοποιητών ως εξής: #include using namespace std; int main() { cout << std::hex << 16 << endl; cout << 16 << endl; cout << std::oct << 16 << endl; cout << 16 << endl; cout << std::dec << 16 << endl; } Στη συγκεκριμένη περίπτωση ο μορφοποιητής, θέτει και μηδενίζει τα //flags// που είναι απαραίτητα ώστε να εκτυπωθεί το περιεχόμενο σε δεκαεξαδική μορφή. ===== Επιλογές μορφοποίησης ενός ostream ===== Τα βασικά //flags// και οι βασικοί μορφοποιητές για τα //flags// αυτά δίνονται παρακάτω: ==== std::ios::boolalpha ==== ^ Group ^ Flag ^ Επεξήγηση ^ | | ''std:ios::boolalpha'' | Εάν το //flag// είναι ενεργό τυπώνει "true"/"false" αντί για "1"/"0" | ^ Μορφοποιητής ^ Επεξήγηση ^ | ''std::boolalpha'' | Εκτυπώνει "true"/"false". | | ''std::noboolalpha'' | Εκτυπώνει "1"/"0". | #include using namespace std; int main() { cout << std::boolalpha << true <<"/"<< false << endl; cout << std::noboolalpha << true <<"/"<< false << endl; } ==== std::ios::basefield ==== ^ Group ^ Flag ^ Επεξήγηση ^ | ''std::ios::basefield'' | ''std:ios::dec'' | Εκτυπώνει σε δεκαδική μορφή. | | ''std::ios::basefield'' | ''std:ios::oct'' | Εκτυπώνει σε οκταδική μορφή. | | ''std::ios::basefield'' | ''std:ios::hex'' | Εκτυπώνει σε δεκαεξαδική μορφή. | ^ Μορφοποιητής ^ Επεξήγηση ^ | ''std::dec'' | Εκτυπώνει σε δεκαδική μορφή. | | ''std::oct'' | Εκτυπώνει σε οκταδική μορφή. | | ''std::hex'' | Εκτυπώνει σε δεκαεξαδική μορφή. | #include using namespace std; int main() { cout.setf(std::ios::dec, std::ios::basefield); cout << 30 << endl; cout.setf(std::ios::oct, std::ios::basefield); cout << 30 << endl; cout.setf(std::ios::hex, std::ios::basefield); cout << 30 << endl; cout << std::dec << 30 << endl; cout << std::oct << 30 << endl; cout << std::hex << 30 << endl; } ==== std::ios::floatfield ==== Εκτύπωση αριθμών κινητής υποδιαστολής ^ Group ^ Flag ^ Επεξήγηση ^ | ''std::ios::floatfield''| ''std::ios::decimal'' | Χρήση δεκαδικής μορφής για την εκτύπωση αριθμών κινητής υποδιστολής. | | ''std::ios::floatfield''| ''std::ios::scientific'' | Χρήση δεκαδικής μορφής για την εκτύπωση αριθμών κινητής υποδιστολής. | | ''std::ios::floatfield''| ''none'' | Χρήση δεκαδικής μορφής για αριθμούς με λίγα ψηφία, διαφορετικά χρήση εκθετικής μορφής. Πρόκειται για την //default// υλοποίηση. | | ''std::ios::floatfield''| ''std::ios::showpoint'' | | ^ Μορφοποιητής ^ Επεξήγηση ^ | ''std::fixed'' | Χρήση δεκαδικής μορφής | | ''std::scientific'' | Χρήση εκθετικής μορφής | | ''std::showpoint'' | Ακόμη και αν ο αριθμός δεν έχει δεκαδικό μέρος, εκτυπώνεται υποχρεωτικά η υποδιαστολή | | ''std::noshowpoint'' | Εάν ο αριθμός δεν έχει δεκαδικό μέρος δεν εκτυπώνεται η υποδιαστολή | | ''std::setprecision(int)'' (iomanip) | To //prototype// βρίσκεται στο αρχείο . Ορίζει την ακρίβεια εκτύπωσης των δεκαδικών ψηφίων του αριθμού. | #include #include using namespace std; int main() { /* no special formatting specified */ cout << 0.00000123456789012345678 << endl; cout << 0.0000123456789012345678 << endl; cout << 0.000123456789012345678 << endl; cout << 0.00123456789012345678 << endl; cout << 0.0123456789012345678 << endl; cout << 0.123456789012345678 << endl; cout << 123.4567890123456789 << endl; cout << 123456.7890123456789 << endl; cout << 123456789.0123456789 << endl; cout << std::showpoint << endl; cout << 30 << " " << 1000L << " " << 1000.00 << " " << 3.14159; cout << std::noshowpoint << endl; cout << 30 << " " << 1000L << " " << 1000.00 << " " << 3.14159; cout << endl; cout << std::fixed << endl; cout << std::setprecision(1) << 123.456 << endl; cout << std::setprecision(2) << 123.456 << endl; cout << std::setprecision(3) << 123.456 << endl; cout << std::setprecision(4) << 123.456 << endl; cout << std::setprecision(5) << 123.456 << endl; cout << std::setprecision(6) << 123.456 << endl; cout << std::setprecision(7) << 123.456 << endl; cout << std::scientific << endl; cout << std::setprecision(1) << 123.456 << endl; cout << std::setprecision(2) << 123.456 << endl; cout << std::setprecision(3) << 123.456 << endl; cout << std::setprecision(4) << 123.456 << endl; cout << std::setprecision(5) << 123.456 << endl; cout << std::setprecision(6) << 123.456 << endl; cout << std::setprecision(7) << 123.456 << endl; } Εάν δεν ορίσετε δικές σας παραμέτρους εκτύπωσης, οι αριθμοί κινητής υποδιαστολής εκτυπώνονται ως εξής: * Εάν ο αριθμός έχει ακέραιο μέρος μεγαλύτερο απο 7 ψηφία, τότε εκτυπώνεται σε εκθετική μορφή. * Εάν ο αριθμός έχει ακέραιο μέρος μηδέν και δεκαδικό μέρος με τέσσερα (4) ή περισσότερα μηδενικά στην αρχή εκτυπώνεται σε εκθετική μορφή. * Σε αντίθετη περίπτωση, * ο αριθμός των εκτυπωσιμων ψηφίων είναι 7, χωρίς να υπολογίζουμε το πρόσημο, την υποδιαστολή και το 0 εάν η απόλυτη τιμή του αριθμού είναι μικρότερη του 1. * Εάν το δεκαδικό μέρος του αριθμού είναι μεγαλύτερο από όσο μπορεί να εκτυπωθεί από την παραπάνω σύμβαση, τότε αυτό αποκόπτεται μετά από στρογγυλοποίηση.