Coming Soon
This lesson is currently being developed
Output with ostream and ios
Write data to output streams with formatting.
What to Expect
Comprehensive explanations with practical examples
Interactive coding exercises to practice concepts
Knowledge quiz to test your understanding
Step-by-step guidance for beginners
Development Status
Content is being carefully crafted to provide the best learning experience
Preview
Early Preview Content
This content is still being developed and may change before publication.
28.3 — Output with ostream and ios
In this lesson, you'll learn how to control output formatting and use various features of C++ output streams. You'll discover how to format numbers, control precision, align text, and customize output to meet your specific needs.
Understanding std::ostream
std::ostream
is the base class for output streams. The most commonly used output stream is std::cout
, but the formatting techniques you'll learn apply to all output streams, including file streams and string streams.
#include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
std::cerr << "This is an error message" << std::endl;
std::clog << "This is a log message" << std::endl;
return 0;
}
Output:
Hello, World!
This is an error message
This is a log message
Basic output formatting
Setting field width
Use std::setw()
to set the minimum width of the next output:
#include <iostream>
#include <iomanip>
int main()
{
std::cout << "Without setw:" << std::endl;
std::cout << 1 << std::endl;
std::cout << 22 << std::endl;
std::cout << 333 << std::endl;
std::cout << "\nWith setw(5):" << std::endl;
std::cout << std::setw(5) << 1 << std::endl;
std::cout << std::setw(5) << 22 << std::endl;
std::cout << std::setw(5) << 333 << std::endl;
return 0;
}
Output:
Without setw:
1
22
333
With setw(5):
1
22
333
Text alignment
Control how text is aligned within the specified width:
#include <iostream>
#include <iomanip>
int main()
{
std::cout << "Left aligned:" << std::endl;
std::cout << std::left;
std::cout << std::setw(10) << "Apple" << "|" << std::endl;
std::cout << std::setw(10) << "Banana" << "|" << std::endl;
std::cout << "\nRight aligned:" << std::endl;
std::cout << std::right;
std::cout << std::setw(10) << "Apple" << "|" << std::endl;
std::cout << std::setw(10) << "Banana" << "|" << std::endl;
std::cout << "\nCenter aligned:" << std::endl;
std::cout << std::internal; // For numbers, affects +/- sign placement
std::cout << std::setw(10) << -123 << "|" << std::endl;
return 0;
}
Output:
Left aligned:
Apple |
Banana |
Right aligned:
Apple|
Banana|
Center aligned:
-123|
Numeric formatting
Setting precision for floating-point numbers
#include <iostream>
#include <iomanip>
int main()
{
double pi = 3.141592653589793;
std::cout << "Default precision: " << pi << std::endl;
std::cout << std::setprecision(3) << "Precision 3: " << pi << std::endl;
std::cout << std::setprecision(6) << "Precision 6: " << pi << std::endl;
std::cout << std::setprecision(10) << "Precision 10: " << pi << std::endl;
return 0;
}
Output:
Default precision: 3.14159
Precision 3: 3.14
Precision 6: 3.14159
Precision 10: 3.141592654
Fixed vs scientific notation
#include <iostream>
#include <iomanip>
int main()
{
double number = 1234.56789;
std::cout << "Default: " << number << std::endl;
std::cout << std::fixed;
std::cout << "Fixed notation: " << number << std::endl;
std::cout << std::scientific;
std::cout << "Scientific notation: " << number << std::endl;
// Reset to default
std::cout.unsetf(std::ios::fixed | std::ios::scientific);
std::cout << "Back to default: " << number << std::endl;
return 0;
}
Output:
Default: 1234.57
Fixed notation: 1234.567890
Scientific notation: 1.234568e+03
Back to default: 1234.57
Controlling decimal places
#include <iostream>
#include <iomanip>
int main()
{
double price = 19.9;
double tax = 0.08;
double total = price * (1 + tax);
std::cout << std::fixed << std::setprecision(2);
std::cout << "Price: $" << price << std::endl;
std::cout << "Tax: $" << (price * tax) << std::endl;
std::cout << "Total: $" << total << std::endl;
return 0;
}
Output:
Price: $19.90
Tax: $1.59
Total: $21.49
Formatting integers
Number base (hexadecimal, octal, decimal)
#include <iostream>
#include <iomanip>
int main()
{
int number = 255;
std::cout << "Decimal: " << std::dec << number << std::endl;
std::cout << "Hexadecimal: " << std::hex << number << std::endl;
std::cout << "Octal: " << std::oct << number << std::endl;
// Show base prefix
std::cout << std::showbase;
std::cout << "With base prefix:" << std::endl;
std::cout << "Decimal: " << std::dec << number << std::endl;
std::cout << "Hexadecimal: " << std::hex << number << std::endl;
std::cout << "Octal: " << std::oct << number << std::endl;
return 0;
}
Output:
Decimal: 255
Hexadecimal: ff
Octal: 377
With base prefix:
Decimal: 255
Hexadecimal: 0xff
Octal: 0377
Fill characters and padding
#include <iostream>
#include <iomanip>
int main()
{
int number = 42;
std::cout << "Default padding:" << std::endl;
std::cout << std::setw(8) << number << std::endl;
std::cout << "Zero padding:" << std::endl;
std::cout << std::setfill('0') << std::setw(8) << number << std::endl;
std::cout << "Star padding:" << std::endl;
std::cout << std::setfill('*') << std::setw(8) << number << std::endl;
// Reset fill character
std::cout << std::setfill(' ');
return 0;
}
Output:
Default padding:
42
Zero padding:
00000042
Star padding:
******42
Boolean output formatting
#include <iostream>
#include <iomanip>
int main()
{
bool flag1 = true;
bool flag2 = false;
std::cout << "Default boolean output:" << std::endl;
std::cout << "flag1: " << flag1 << std::endl;
std::cout << "flag2: " << flag2 << std::endl;
std::cout << std::boolalpha; // Show as text
std::cout << "Text boolean output:" << std::endl;
std::cout << "flag1: " << flag1 << std::endl;
std::cout << "flag2: " << flag2 << std::endl;
return 0;
}
Output:
Default boolean output:
flag1: 1
flag2: 0
Text boolean output:
flag1: true
flag2: false
Creating formatted tables
#include <iostream>
#include <iomanip>
#include <string>
int main()
{
// Data to display
std::string names[] = {"Alice", "Bob", "Charlie"};
int ages[] = {25, 30, 35};
double salaries[] = {50000.50, 65000.75, 80000.00};
// Table header
std::cout << std::left << std::setfill(' ');
std::cout << std::setw(10) << "Name"
<< std::setw(6) << "Age"
<< std::setw(12) << "Salary" << std::endl;
std::cout << std::setw(28) << std::setfill('-') << "" << std::endl;
std::cout << std::setfill(' ');
// Table data
for (int i = 0; i < 3; ++i)
{
std::cout << std::left << std::setw(10) << names[i]
<< std::right << std::setw(6) << ages[i]
<< std::fixed << std::setprecision(2)
<< std::setw(12) << salaries[i] << std::endl;
}
return 0;
}
Output:
Name Age Salary
----------------------------
Alice 25 50000.50
Bob 30 65000.75
Charlie 35 80000.00
Stream manipulators
Persistent vs non-persistent manipulators
#include <iostream>
#include <iomanip>
int main()
{
// setw is non-persistent (affects only the next output)
std::cout << std::setw(5) << 1 << std::setw(5) << 2 << std::endl;
std::cout << 3 << 4 << std::endl; // No width formatting
// setprecision is persistent (affects all subsequent output)
std::cout << std::setprecision(2);
std::cout << 3.14159 << " " << 2.71828 << std::endl;
return 0;
}
Output:
1 2
34
3.1 2.7
Custom manipulators
You can create your own stream manipulators:
#include <iostream>
#include <iomanip>
// Custom manipulator to format currency
std::ostream& currency(std::ostream& os)
{
return os << std::fixed << std::setprecision(2) << "$";
}
int main()
{
double price = 19.9;
std::cout << "Price: " << currency << price << std::endl;
std::cout << "Tax: " << currency << (price * 0.08) << std::endl;
return 0;
}
Output:
Price: $19.90
Tax: $1.59
Using ios flags directly
You can also manipulate formatting using ios flags:
#include <iostream>
int main()
{
double number = 1234.5;
// Set flags using setf()
std::cout.setf(std::ios::fixed);
std::cout.setf(std::ios::showpoint);
std::cout.precision(3);
std::cout << "With flags: " << number << std::endl;
// Unset flags using unsetf()
std::cout.unsetf(std::ios::fixed);
std::cout << "Without fixed: " << number << std::endl;
return 0;
}
Output:
With flags: 1234.500
Without fixed: 1.23e+03
Output stream states and error handling
#include <iostream>
int main()
{
std::cout << "Before output, stream state: " << std::cout.good() << std::endl;
std::cout << "Hello, World!" << std::endl;
// Check stream state after output
if (std::cout.good())
{
std::cout << "Output operation was successful" << std::endl;
}
else if (std::cout.fail())
{
std::cout << "Output operation failed" << std::endl;
}
return 0;
}
Output:
Before output, stream state: 1
Hello, World!
Output operation was successful
Formatting for different data displays
Progress bar example
#include <iostream>
#include <iomanip>
void displayProgress(int percentage)
{
int barWidth = 40;
int filled = (percentage * barWidth) / 100;
std::cout << "[";
std::cout << std::setfill('=') << std::setw(filled) << "";
std::cout << std::setfill(' ') << std::setw(barWidth - filled) << "";
std::cout << "] " << std::setw(3) << percentage << "%\r";
std::cout.flush();
}
int main()
{
for (int i = 0; i <= 100; i += 10)
{
displayProgress(i);
// In a real program, you'd have some work here
}
std::cout << std::endl;
return 0;
}
Output:
[========================================] 100%
Financial report formatting
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::fixed << std::setprecision(2);
std::cout << std::right;
std::cout << "Financial Report" << std::endl;
std::cout << std::setfill('=') << std::setw(30) << "" << std::endl;
std::cout << std::setfill(' ');
std::cout << std::setw(20) << "Revenue:" << std::setw(10) << 150000.00 << std::endl;
std::cout << std::setw(20) << "Expenses:" << std::setw(10) << 95000.50 << std::endl;
std::cout << std::setfill('-') << std::setw(30) << "" << std::endl;
std::cout << std::setfill(' ');
std::cout << std::setw(20) << "Net Profit:" << std::setw(10) << (150000.00 - 95000.50) << std::endl;
return 0;
}
Output:
Financial Report
==============================
Revenue: 150000.00
Expenses: 95000.50
------------------------------
Net Profit: 54999.50
Best practices for output formatting
✅ Good practices:
#include <iostream>
#include <iomanip>
int main()
{
// Save original format state
std::ios_base::fmtflags originalFlags = std::cout.flags();
int originalPrecision = std::cout.precision();
// Apply temporary formatting
std::cout << std::fixed << std::setprecision(2);
std::cout << "Formatted output: " << 3.14159 << std::endl;
// Restore original format state
std::cout.flags(originalFlags);
std::cout.precision(originalPrecision);
std::cout << "Back to original: " << 3.14159 << std::endl;
return 0;
}
❌ Common mistakes:
#include <iostream>
#include <iomanip>
int main()
{
// Bad: Not considering persistent manipulators
std::cout << std::setprecision(2);
std::cout << 3.14159 << std::endl; // Precision affects this
std::cout << 2.71828 << std::endl; // And this too!
// Bad: Inconsistent table formatting
std::cout << std::setw(5) << "Name" << "Age" << std::endl; // Only first column formatted
return 0;
}
Summary
Effective output formatting with std::ostream
includes:
- Width control with
std::setw()
for aligned output - Precision control with
std::setprecision()
for floating-point numbers - Alignment options with
std::left
,std::right
, andstd::internal
- Number base formatting with
std::hex
,std::oct
, andstd::dec
- Fill characters with
std::setfill()
for custom padding - Boolean formatting with
std::boolalpha
for text output - Stream state management for maintaining format consistency
Mastering output formatting allows you to create professional-looking displays, reports, and user interfaces that enhance the usability of your programs.
Quiz
- What's the difference between persistent and non-persistent manipulators?
- How do you display a floating-point number with exactly 2 decimal places?
- What's the purpose of
std::setfill()
? - How can you display a boolean value as "true"/"false" instead of 1/0?
- Why might you want to save and restore stream format flags?
Practice exercises
Apply your output formatting skills with these exercises:
-
Student Report Card: Create a formatted table showing student names, grades for 3 subjects, and average grades with proper alignment.
-
Number Converter: Write a program that displays the same number in decimal, hexadecimal, and octal formats with proper labeling.
-
Invoice Generator: Create a formatted invoice with item names, quantities, prices, and totals properly aligned with currency formatting.
-
Progress Monitor: Build a progress indicator that shows completion percentage with both a progress bar and numeric percentage.
Explore More Courses
Discover other available courses while this lesson is being prepared.
Browse CoursesLesson Discussion
Share your thoughts and questions