Console Input and Output

Formatting Console Output with <iomanip>

Look at these two console outputs showing a simple shopping receipt:

Apple 0.99
Watermelon 4.5
Total 5.49
Apple          $0.99
Watermelon     $4.50
Total          $5.49

As you can see, in the first one the numbers do not match and the price of the watermelon has no ending zero. In the second one, all the columns are well-aligned and the prices always contain two decimals. All this formatting is provided by the C++ with the standard input-output manipulators library.

First, include the necessary header in your code:

#include <iomanip>

All the manipulators from the input-output manipulators library are sent to the standard output stream using the stream insertion operator like strings or variables.

Some formatting manipulators have a different lifetime. std::fixed, std::scientific, std::left, and std::setprecision stay active until changed. std::setw is active only for the next formatted item, so you need to set it again for every column that needs a width.

The std::setw width manipulator reserves the certain number of character spaces for the next item you are going to print. If the item is smaller than the specified width, the C++ will add empty spaces. Look at this example of the code:

#include <iostream>
#include <iomanip>

int main() {
    std::cout << std::setw(10) << "Apple" << std::setw(8) << 0.99 << "\n";
    std::cout << std::setw(10) << "Banana" << std::setw(8) << 1.25 << "\n";
    return 0;
}

By default, the std::setw width manipulator makes text right-aligned in the reserved space. However, you can change the alignment with the std::left and std::right alignment manipulators. Do not forget that std::setw is active only for the next single item to print. Alignment manipulators are sticky, so they will affect all subsequent output till you will change them explicitly.

Controlling Decimal Places and Width

The std::setfill fill manipulator changes the padding character and the alignment manipulator determines whether the padding is on the left or on the right. The width is the minimum and not maximum. Values larger than the requested width are printed entirely. Formatting affects the presentation only and not the actual values stored in variables. Reset std::defaultfloat and other default stream states when the helper function should not change them.

By default, when printing the floating-point values, C++ prints up to six significant digits. C++ also may switch to the scientific notation for too large or too small values. Forcing the console to print the certain number of decimal places requires using the combination of std::fixed and std::setprecision.

The std::fixed manipulator forces the stream to print numbers in the fixed-point notation and not in scientific. The std::setprecision manipulator defines the number of digits to print. Combined with std::fixed, std::setprecision shows how many digits after the dot should be printed. Both manipulators are sticky, so they affect every subsequent number printed to the stream till changing them.

Here is the example combining these manipulators for making the whole table formatted:

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

int main() {
    double price1 = 0.99;
    double price2 = 4.5;
    double total = price1 + price2;

    std::cout << std::fixed << std::setprecision(2);

    std::cout << std::left << std::setw(15) << "Item" << std::right << std::setw(10) << "Price" << "\n";
    std::cout << "-------------------------\n";

    std::cout << std::left << std::setw(15) << "Apple" << std::right << "$" << std::setw(9) << price1 << "\n";
    std::cout << std::left << std::setw(15) << "Watermelon" << std::right << "$" << std::setw(9) << price2 << "\n";
    std::cout << "-------------------------\n";
    std::cout << std::left << std::setw(15) << "Total" << std::right << "$" << std::setw(9) << total << "\n";

    return 0;
}

std::setw(9) is applied to the price variables. However, as the currency sign is printed before the price, the whole width of the price column is aligned. As std::left and std::right alignments are sticky, you need to switch them explicitly for every column to align the text and numbers properly.

Exercise: Formatting Console Output with <iomanip>Starter code, hints and solutionOpenClose
Guided practiceBeginner · 10–15 min

Practice: Formatting Console Output with <iomanip>

Work through the mission, reveal hints only when needed, and compare your result with the model solution.

Your challenge

Change the second item price to 5.00 and retain two decimal places. Predict the new item price and total while keeping the table formatting.

Mission checklist

  1. Run the starter as a baseline, then predict the change requested in Your challenge.
  2. Make that change in your editor; use the lesson-specific hints if you need help.
  3. Compile and run your answer, then compare with the worked solution and explain the result.

Starter program

This is the working baseline, not the completed answer. Compile as C++20, then make the change described above.

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

int main() {
    double price1 = 0.99;
    double price2 = 4.5;
    double total = price1 + price2;

    std::cout << std::fixed << std::setprecision(2);

    std::cout << std::left << std::setw(15) << "Item" << std::right << std::setw(10) << "Price" << "\n";
    std::cout << "-------------------------\n";

    std::cout << std::left << std::setw(15) << "Apple" << std::right << "$" << std::setw(9) << price1 << "\n";
    std::cout << std::left << std::setw(15) << "Watermelon" << std::right << "$" << std::setw(9) << price2 << "\n";
    std::cout << "-------------------------\n";
    std::cout << std::left << std::setw(15) << "Total" << std::right << "$" << std::setw(9) << total << "\n";

    return 0;
}

Hints

Hint 1

With std::fixed active, setprecision(2) controls digits after the decimal point. Changing price2 affects both its row and total.

Hint 2

setw applies to the next formatted value, whereas left, right, and the precision remain active. Track the separate "$" insertion before each price field.

Worked solution

price2 is now 5.00, so total becomes 5.99. fixed and setprecision(2) keep two digits after the decimal point, while setw and the alignment manipulators keep the table fields aligned.

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

int main() {
    double price1 = 0.99;
    double price2 = 5.0;
    double total = price1 + price2;

    std::cout << std::fixed << std::setprecision(2);

    std::cout << std::left << std::setw(15) << "Item" << std::right << std::setw(10) << "Price" << "\n";
    std::cout << "-------------------------\n";

    std::cout << std::left << std::setw(15) << "Apple" << std::right << "$" << std::setw(9) << price1 << "\n";
    std::cout << std::left << std::setw(15) << "Watermelon" << std::right << "$" << std::setw(9) << price2 << "\n";
    std::cout << "-------------------------\n";
    std::cout << std::left << std::setw(15) << "Total" << std::right << "$" << std::setw(9) << total << "\n";

    return 0;
}

Example output

Item                Price
-------------------------
Apple          $     0.99
Watermelon     $     5.00
-------------------------
Total          $     5.99

0 comments

No comments yet. Be the first.

Add a comment

About CppLearn

CppLearn is an interactive, free reference for modern C++. In each lesson, you'll find out how the language works, rather than just lines of code that you can copy and paste. We cover concepts starting from beginner lessons on fundamentals and proceed to templates, move semantics, smart pointers, and areas that usually trap or scare C++ learners.