Science and technology

Suggestions for formatting when printing to console from C++

When I began writing, I did it primarily for the aim of documenting for myself. When it involves programming, I’m extremely forgetful, so I started to jot down down helpful code snippets, particular traits, and customary errors within the programming languages I take advantage of. This article completely matches the unique thought because it covers widespread use circumstances of formatting when printing to console from C++.

[Download the C++ std::cout cheat sheet]

As normal, this text comes with a whole lot of examples. Unless in any other case acknowledged, every kind and lessons proven within the code snippets are a part of the std namespace. So if you are studying this code, it’s a must to put utilizing namespace std; in entrance of varieties and lessons. Of course, the instance code can also be obtainable on GitHub.

Object-oriented stream

If you’ve got ever programmed in C++, you’ve got definitely already used cout. The cout object of kind ostream comes into scope whenever you embrace <iostream>. This article focuses on cout, which helps you to print to the console however the common formatting described right here is legitimate for all stream objects of kind ostream. An ostream object is an occasion of basic_ostream with the template parameter of kind char. The header <iosfwd>, which is a part of the embrace hierarchy of <iostream>, incorporates ahead declarations for widespread varieties.

The class basic_ostream inherits from basic_ios and this sort, in flip, inherits from ios_base. On cppreference.com you discover a class diagram that reveals the connection between the totally different lessons.

The class ios_base is the bottom class for all I/O stream lessons. The class basic_ios is a template class that has a specialization for widespread character varieties referred to as ios. So whenever you examine ios within the context of ordinary I/O, it’s the char-type specialization of basic_ios.

Formatting streams

In common, there are 3 ways of formatting ostream-based streams:

  1. Using the format flags offered by ios_base.
  2. Stream modifying capabilities outlined within the header <iomanip> and <ios>.
  3. By invoking a specific overload of the <<-operator.

All strategies have their execs and cons, and it often will depend on the scenario when which technique is used. The following examples present a combination of all strategies.

Right justified

By default, cout occupies as a lot house as the info to print requires. To enable that right-justified output to take impact, it’s a must to outline the utmost width {that a} line is allowed to occupy. I take advantage of the format flags to achieve the aim.

The flag for right-justified output and the width adjustment solely applies to the next line:

cout.setf(ios::proper, ios::adjustfield);
cout.width(50);
cout << "This text is right justified" << endl;
cout << "This text is left justified again" << endl;

In the above code, I configure the right-justified output utilizing setf. I like to recommend you apply the bitmask ios::adjustfield to setf, which causes all flags the bitmask specifies to be reset earlier than the precise ios::proper flag will get set to stop colliding combos.

Fill white house

When utilizing right-justified output, the empty house is crammed with blanks by default. You can change it by specifying the fill character utilizing setfill:

cout << proper << setfill('.') << setw(30) << 500 << " pcs" << endl;
cout << proper << setfill('.') << setw(30) << 3000 << " pcs" << endl;
cout << proper << setfill('.') << setw(30) << 24500 << " pcs" << endl;

The code produces the next output:

...........................500 pcs
..........................3000 pcs
.........................24500 pcs

Combine 

Imagine your C++ program retains observe of your pantry stock. From time to time, you need to print a listing of the present inventory. To achieve this, you might use the next formatting.

The following code is a mix of left- and right-justified output utilizing dots as fill characters to get a pleasant wanting listing:

cout << left << setfill('.') << setw(20) << "Flour" << proper << setfill('.') << setw(20) << 0.7 << " kg" << endl;
cout << left << setfill('.') << setw(20) << "Honey" << proper << setfill('.') << setw(20) << 2 << " Glasses" << endl;
cout << left << setfill('.') << setw(20) << "Noodles" << proper << setfill('.') << setw(20) << 800 << " g" << endl;
cout << left << setfill('.') << setw(20) << "Beer" << proper << setfill('.') << setw(20) << 20 << " Bottles" << endl;

Output:

Flour...............................0.70 kg
Honey..................................2 Glasses
Noodles..............................800 g
Beer..................................20 Bottles

Printing values

Of course, stream-based output additionally affords a mess of prospects to output every kind of variable varieties.

Boolean

The boolalpha change helps you to convert the binary interpretation of a bool to a string:

cout << "Boolean output without using boolalpha: " << true << " / " << false << endl;
cout << "Boolean output using boolalpha: " << boolalpha << true << " / " << false << endl;

The traces above produce the next output:

Boolean output with out utilizing boolalpha: 1 / 0
Boolean output utilizing boolalpha: true / false

Addresses

If the worth of an integer ought to be handled as an tackle, it’s enough to forged it to void* with a view to invoke the proper overload. Here is an instance:

unsigned lengthy someAddress = 0x0000ABCD;
cout << "Treat as unsigned long: " << someAddress << endl;
cout << "Treat as address: " << (void*)someAddress << endl;

The code produces the next output:

Treat as unsigned lengthy: 43981
Treat as tackle: 0000ABCD

The code prints the tackle with the proper size. A 32-bit executable produced the above output.

Integers

Printing integers is easy. For demonstration objective I specify the bottom of the quantity utilizing setf and setiosflags. Applying the stream modifiers hex/oct would have the identical impact:

int myInt = 123;

cout << "Decimal: " << myInt << endl;

cout.setf(ios::hex, ios::basefield);
cout << "Hexadecimal: " << myInt << endl;

cout << "Octal: " << resetiosflags(ios::basefield) <<  setiosflags(ios::oct) << myInt << endl;

Note: There isn’t any indicator for the used base by default, however you may add one utilizing showbase.

Decimal: 123
Hexadecimal: 7b
Octal: 173

Padding with zeros

0000003
0000035
0000357
0003579

You can get an output just like the above by specifying the width and the fill character:

cout << setfill('0') << setw(7) << 3 << endl;
cout << setfill('0') << setw(7) << 35 << endl;
cout << setfill('0') << setw(7) << 357 << endl;
cout << setfill('0') << setw(7) << 3579 << endl;

Floating-point values

If I need to print floating-point values, I can select between the fastened– and scientific-format. Additionally, I can specify the precision.

double myFloat = 1234.123456789012345;
int defaultPrecision = cout.precision(); // == 2

cout << "Default precision: " << myFloat << endl;
cout.precision(4);
cout << "Modified precision: " << myFloat << endl;
cout.setf(ios::scientific, ios::floatfield);
cout << "Modified precision & scientific format: " << myFloat << endl;
/* again to default */
cout.precision(defaultPrecision);
cout.setf(ios::fastened, ios::floatfield);
cout << "Default precision & fixed format:  " << myFloat << endl;

The code above produces the next output:

Default precision: 1234.12
Modified precision: 1234.1235
Modified precision & scientific format: 1.2341e+03
Default precision & fastened format:  1234.12

Time and Money

With put_money, you may print forex models within the right, locale-dependent formatting. This requires that your console can output UTF-8 charset. Note that the variable particularOffering shops the financial worth in cents:

lengthy double particularOffering = 9995;

cout.imbue(locale("en_US.UTF-8"));
cout << showbase << put_money(particularOffering) << endl;
cout.imbue(locale("de_DE.UTF-8"));
cout << showbase << put_money(particularOffering) << endl;
cout.imbue(locale("ru_RU.UTF-8"));
cout  << showbase << put_money(particularOffering) << endl;

The imbue-method of ios helps you to specify a locale. With the command locale -a, you may get a listing of all obtainable locale identifiers in your system. 


(For no matter purpose, it prints euro and ruble with three decimal locations on my system, which appears to be like unusual for me, however possibly that is the official formatting.)

The similar precept applies to time output. The perform put_time helps you to print the time within the corresponding locale format. Additionally, you may specify which elements of a time object get printed.

time_t now = time(nullptr);
tm localtm = *localtime(&now);

cout.imbue(locale("en_US.UTF-8"));
cout << "en_US : " << put_time(&localtm, "%c") << endl;
cout.imbue(locale("de_DE.UTF-8"));
cout << "de_DE : " << put_time(&localtm, "%c") << endl;
cout.imbue(locale("ru_RU.UTF-8"));
cout << "ru_RU : " << put_time(&localtm, "%c") << endl;

The format specifier %c causes to print a typical date and time string:

en_US : Tue 02 Nov 2021 07:36:36 AM CET
de_DE : Di 02 Nov 2021 07:36:36 CET
ru_RU : Вт 02 ноя 2021 07:36:36

Creating customized stream modifiers

You may also create your individual stream. The following code inserts a predefined string when utilized to an ostream object:

ostream& myManipulator(ostream& os) {
    string myStr = ">>>Here I am<<<";
    os << myStr;
    return os;
}

Another instance: If you may have one thing essential to say, like most individuals on the web, you might use the next code to insert exclamation marks after your message relying on the extent of significance. The stage of significance will get handed as an argument:

struct T_Importance {
     int stageOfSignificance;
};

T_Importance significance(int lvl){
    T_Importance x = {.stageOfSignificance = lvl };
    return x;
}

ostream& operator<<(ostream& __os, T_Importance t){

    for(int i = 0; i < t.stageOfSignificance; ++i){
        __os.put('!');
    }
    return __os;
}

Both modifiers can now be merely handed to cout:

cout << "My custom manipulator: " << myManipulator << endl;

cout << "I have something important to say" << significance(5) << endl;

Producing the next output:

My customized manipulator: >>>Here I'm

I've one thing essential to say!!!!!

Conclusion

Next time you battle with console output formatting, I hope you keep in mind this text or the associated cheat sheet.

In C++ purposes, cout is the brand new neighbor of printf. While utilizing printf continues to be legitimate, I might most likely at all times choose utilizing cout. Especially the mix with the modifying perform outlined in <ios> ends in good, readable code.

Most Popular

To Top