User Tools

Site Tools


cpp:osteams

Output Streams

Όπως προαναφέρθηκε τα streams εξόδου χρησιμοποιούν τον τελεστη « (stream insertion operator) για εγγραφή στο stream. Σε αναλογία με τα input streams, η standard βιβλιοθήκη παρέχει συναρτήσεις υπεφόρτωσης για τους βασικούς τύπους δεδομένων, ενώ δίνεται η δυνατότητα υπερφόρτωσης για όλους τους μη βασικούς τύπους που θα χρειαστεί να κατασκευάσετε στα προγράμματα σας. Το παρακάτω παράδειγμα γραψίματος στην κονσόλα (stdout) είναι ενδεικτικό.

stdout.cpp
#include <iostream>
 
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 με τους εξής δύο τρόπους:

  • χρησιμοποιώντας τις συναρτήσεις μορφοποίησης setf (ενεργοποιεί ένα flag που συνδέεται με μία επιλογή μορφοποίησης) και unsetf (απενεργοποιεί ένα flag που συνδέεται με μία επιλογή μορφοποίησης).
  • χρησιμοποιώντας μορφοποιητές (manipulators) πάνω στο stream.

Χρήση συναρτήσεων μορφοποίησης

Ας υποθέσουμε ότι σε ένα stream θέλουμε η αριθμοί να εκτυπώνονται σε δεκαεξαδική μορφή. Προκειμένου να το πετύχουμε αυτό, θα πρέπει να κάνουμε τα εξής:

ostream-setf.cpp
#include <iostream>
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.

ostream-setf2.cpp
#include <iostream>
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 και χρησιμοποιούνται ευρέως. Για παράδειγμα το προηγούμενο πρόγραμμα μπορεί να γραφεί με χρήση μορφοποιητών ως εξής:

ostream-manipulators.cpp
#include <iostream>
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”.
boolalpha.cpp
#include <iostream>
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 Εκτυπώνει σε δεκαεξαδική μορφή.
ostream-basefield.cpp
#include <iostream>
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 βρίσκεται στο αρχείο <iomanip>. Ορίζει την ακρίβεια εκτύπωσης των δεκαδικών ψηφίων του αριθμού.
ostream-floatfield.cpp
#include <iostream>
#include <iomanip>
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.
    • Εάν το δεκαδικό μέρος του αριθμού είναι μεγαλύτερο από όσο μπορεί να εκτυπωθεί από την παραπάνω σύμβαση, τότε αυτό αποκόπτεται μετά από στρογγυλοποίηση.
cpp/osteams.txt · Last modified: 2020/05/17 18:10 (external edit)