Coming Soon

This lesson is currently being developed

Output with ostream and ios

Write data to output streams with formatting.

Input and Output (I/O)
Chapter
Beginner
Difficulty
40min
Estimated Time

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

In Progress

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, and std::internal
  • Number base formatting with std::hex, std::oct, and std::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

  1. What's the difference between persistent and non-persistent manipulators?
  2. How do you display a floating-point number with exactly 2 decimal places?
  3. What's the purpose of std::setfill()?
  4. How can you display a boolean value as "true"/"false" instead of 1/0?
  5. Why might you want to save and restore stream format flags?

Practice exercises

Apply your output formatting skills with these exercises:

  1. Student Report Card: Create a formatted table showing student names, grades for 3 subjects, and average grades with proper alignment.

  2. Number Converter: Write a program that displays the same number in decimal, hexadecimal, and octal formats with proper labeling.

  3. Invoice Generator: Create a formatted invoice with item names, quantities, prices, and totals properly aligned with currency formatting.

  4. Progress Monitor: Build a progress indicator that shows completion percentage with both a progress bar and numeric percentage.

Continue Learning

Explore other available lessons while this one is being prepared.

View Course

Explore More Courses

Discover other available courses while this lesson is being prepared.

Browse Courses

Lesson Discussion

Share your thoughts and questions

💬

No comments yet. Be the first to share your thoughts!

Sign in to join the discussion