Skip to Content
Course content

197: Stream Manipulators for Formatted Output

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was reviewing a pull request from a junior dev who was building a simple CLI-based accounting tool. He had spent nearly an entire afternoon manually adding spaces to his std::cout statements—literally typing " "—to try and get the currency columns to line up. It looked fine on his machine, but the second a value jumped from two digits to four, the entire table shifted, and the report looked like a jumbled mess. I remember laughing, not at him, but at the "brute force" approach we've all tried at least once before discovering that C++ has a built-in way to handle this.

Taming the Floating Point Chaos

If you've worked with double or float, you know that C++ is notoriously "helpful" with scientific notation. You'll be printing a price, and suddenly it shows up as 1.2e+02 because the number got too large or too small. To stop this, we use the <iomanip> header, which gives us access to stream manipulators.

The most important duo here is std::fixed and std::setprecision(). When you use std::fixed, you're telling the stream, "Stop using scientific notation; I want a fixed number of decimal places." Pair that with std::setprecision(n), and you can lock the output to exactly n digits after the decimal point. I usually set this to 2 for anything involving money.

#include <iostream>
#include <iomanip>

double balance = 1234.5;
// Without manipulators, this might just print "1234.5"
// We want "1234.50"
std::cout << std::fixed << std::setprecision(2) << balance << std::endl; 
// Output: 1234.50

Aligning Columns with setw and Alignment Flags

Once your numbers are formatted, you still have the problem of alignment. This is where std::setw(n) comes in. Unlike std::fixed, which stays in effect until you change it, std::setw is "one-shot." It only affects the very next item you pipe into the stream. I've lost a bit of time in the past forgetting this and wondering why my entire list wasn't aligned—you have to call it for every single column.

By default, setw right-aligns the text. To change that, we use std::left or std::right. These are persistent, so once you set the stream to std::left, it stays that way until you tell it otherwise. Here is how I typically structure a clean data row:

#include <iostream>
#include <iomanip>
#include <string>

std::string item = "Widget A";
double price = 25.99;
int qty = 3;

std::cout << std::left << std::setw(15) << item 
          << std::right << std::setw(10) << std::fixed << std::setprecision(2) << price 
          << std::right << std::setw(5) << qty << std::endl;
// Output: Widget A            25.99    3

It looks a bit verbose at first, but it's infinitely better than guessing how many spaces a string needs. Just remember: setw is a temporary nudge for the next element; fixed, setprecision, and left/right are permanent state changes for the stream.




📋 Practical Task

Building a Formatted Transaction Ledger

Your task is to create a program that prints a professional-looking transaction ledger. You are provided with a list of transactions (item name, cost, and quantity), and you must display them in a perfectly aligned table.

Requirements:

  • Include the <iomanip> header.
  • Print a header row: "Item", "Price", and "Qty".
  • The "Item" column must be left-aligned with a width of 20 characters.
  • The "Price" column must be right-aligned with a width of 10 characters and strictly formatted to 2 decimal places.
  • The "Qty" column must be right-aligned with a width of 5 characters.
  • Use the following data for your output:
    • "Gaming Mouse", 49.99, 2
    • "Mechanical Keyboard", 120.0, 1
    • "USB-C Cable", 15.5, 5

Make sure your header row and your data rows use the exact same setw values so the columns line up perfectly!

Rating
0 0

There are no comments for now.

to be the first to leave a comment.