Home > Mobile >  Width and setfill('-') in cpp
Width and setfill('-') in cpp

Time:11-30

I am new to C and am wondering if there is a more elegant way to print out the following:

Celsius  Kelvin  Fahrenheit  Reaumur
-------------------------------------

I guess you could just do

cout << "Celsius  Kelvin  Fahrenheit  Reaumur" << endl << "-------------------------------------";

But it doesn't look good. In Ada you could do "Width". Is there a similiar operator in cpp? And can you not just do setfill('-') and the amount of '-' you want to print out?

Any help is greatly appreciated

CodePudding user response:

Here are two other ways to produce this line:

    std::cout << "-------------------------------------\n";

std::setfill std::setw:

#include <iomanip>

    std::cout << std::setfill('-') << std::setw(38) << '\n';

Using a std::string:

#include <string>

    std::cout << std::string(37, '-') << '\n';

Demo

CodePudding user response:

You could (and probably should) use std::format. Also see the fmtlib/fmt library:

Both format and fmtlib use the format spec':

Also see this question which features several related answers:


You can tweak this very easily to make this fit your needs (I made some deliberate imperfections for the sake of clarity):

#include <fmt/core.h>

int main() {
    int const width = 12;

    // See https://en.cppreference.com/w/cpp/utility/format/format
    // ^ centres the field (with default space fill)
    // -^ centres the field with "-" fill
    // 12 and 52 are specific field widths.
    // inner {} means the field width is provided by the next parameter

    fmt::print("_{:^{}} {:^{}} {:^{}} {:^12}_\n-{:-^52}\n", 
            "Celsius", width,
            "Kelvin", width,
            "Farenheit", width,
            "Reaumur",
            "=");
}

Output:

_  Celsius       Kelvin     Farenheit     Reaumur   _
--------------------------=--------------------------

FmtLib Demo: https://godbolt.org/z/463xWvx5P

Format Demo: https://godbolt.org/z/MP9sac7ba (thanks Ted)

CodePudding user response:

Big fan of separating this out for re-use and easier reading. Example:

std::ostream & draw_heading(std::ostream & out,
                            const std::string & heading)
{
    char old_fill = out.fill('-');
    std::streamsize old_width = out.width();
    out << h.mHeading << '\n'
        << std::setw(h.mHeading.size()   1) << '\n';
    out.width(old_width);
    out.fill(old_fill);
    return out;
}

Only does the writing and will write to any output stream. It returns a reference to the stream so it can be easily tested for success or chained.

Basic Usage:

draw_heading(std::cout, "Celsius  Kelvin  Fahrenheit  Reaumur");

The ugly stuff is now buried away from the main logic, which can get on with whatever the heck its job is.

CodePudding user response:

You can use the literal string feature:

#include <string>
#include <iostream>

int main()
{
    std::cout << R"(
This is a line of text with an underline
----------------------------------------
)";

}

This allows you to add all the explicit characters you want (including newline) which makes the layout of large chunks of text nicer (relatively) to do in code.

I just wish that the R"( ignored the first newline if it is the only character on that line. But it still looks better than:

cout << "Celsius  Kelvin  Fahrenheit  Reaumur\n"
     << "------------------------------------\n";

or

cout << "Celsius  Kelvin  Fahrenheit  Reaumur\n"
     << std::string(38, '-') << "\n";
  •  Tags:  
  • c
  • Related