====== 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.
* Εάν το δεκαδικό μέρος του αριθμού είναι μεγαλύτερο από όσο μπορεί να εκτυπωθεί από την παραπάνω σύμβαση, τότε αυτό αποκόπτεται μετά από στρογγυλοποίηση.