user3340001
user3340001

Reputation: 237

Aligning output on the right in c++

#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
    cout << right << "Hello" << setw(10) << "World\n";
    cout << right << "Goodbye"  << setw(10) << "World\n";
}

Why does this result in output like:

Hello    World
Goodbye    World

Rather than:

Hello    World
Goodbye  World

What am I doing wrong here?

EDIT:

#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
    cout    << "Hello"  <<  " World";
    cout << right << setw(10) << "today\n";
    cout   << "Goodbye"  <<  " World";
    cout << right << setw(10) << "today\n";
}

If I try this, why is the "today" part misaligned?

Upvotes: 8

Views: 22773

Answers (4)

Idan Yehuda
Idan Yehuda

Reputation: 562

try this -

    cout << right << "Hello" << "\t" << "World\n";
    cout << right << "Goodbye"  <<  "\t" << "World\n";

Upvotes: 0

Holger Strauss
Holger Strauss

Reputation: 285

This is a solution using std::format (C++20):

#include <format>
#include <iostream>

int main() {
    std::cout << std::format("{:10}{:}\n", "Hello",   "World");
    std::cout << std::format("{:10}{:}\n", "Goodbye", "World");
    }

Upvotes: 2

Flovdis
Flovdis

Reputation: 3095

Change the order of the operators to solve this problem:

#include <iostream>
#include <iomanip>

int main()
{
    std::cout << std::left << std::setw(10) << "Hello" << "World\n";
    std::cout << std::left << std::setw(10) << "Goodbye" << "World\n";
    return 0;
}
  • You have to place all operators before the value you like to format.
  • Avoid using using namespace std.

The std::setw() operator sets the field with for the next value. And the std::left or std::right operators set the position of the value in this field.

This example

std::cout << std::left << std::setw(10) << "word1"
    << std::right << std::setw(20) << "word2" << std::endl;

Will create this kind of formatting:

AAAAAAAAAABBBBBBBBBBBBBBBBBBBB
word1                    word2

You see there is a first "field" with 10 characters in which the first text is placed, and a second "field" with 20 characters in which the second word is placed right aligned. But if the text in the first field is longer than the field, this happens:

AAAAAAAAAA....BBBBBBBBBBBBBBBBBBBB
word1istoolong               word2

The second field is just shifted the number of characters. The stream never keeps track of the current position, it just build the output using "fields" of a given size.

To justify text for a given page with, use code like this:

#include <iostream>
#include <sstream>
#include <list>

const int pageWidth = 78;
typedef std::list<std::string> WordList;

WordList splitTextIntoWords( const std::string &text )
{
    WordList words;
    std::istringstream in(text);
    std::string word;
    while (in) {
        in >> word;
        words.push_back(word);
    }
    return words;
}

void justifyLine( std::string line )
{
    size_t pos = line.find_first_of(' ');
    if (pos != std::string::npos) {
        while (line.size() < pageWidth) {
            pos = line.find_first_not_of(' ', pos);
            line.insert(pos, " ");
            pos = line.find_first_of(' ', pos+1);
            if (pos == std::string::npos) {
                pos = line.find_first_of(' ');
            }
        }
    }
    std::cout << line << std::endl;
}

void justifyText( const std::string &text )
{
    WordList words = splitTextIntoWords(text);

    std::string line;
    for (WordList::const_iterator it = words.begin(); it != words.end(); ++it) {
        if (line.size() + it->size() + 1 > pageWidth) { // next word doesn't fit into the line.
            justifyLine(line);
            line.clear();
            line = *it;
        } else {
            if (!line.empty()) {
                line.append(" ");
            }
            line.append(*it);
        }
    }
    std::cout << line << std::endl;
}

int main()
{
    justifyText("This small code sample will format a paragraph which "
        "is passed to the justify text function to fill the "
        "selected page with and insert breaks where necessary. "
        "It is working like the justify formatting in text "
        "processors.");
    return 0;
}

This example justifies each line to fill the given page with at the begin. It works by splitting the text into words, filling lines with these words, and justifies each line to exactly match the width.

Upvotes: 9

Gassa
Gassa

Reputation: 8846

The problem is, at the point you call setw, the output stream does not remember about printing "Hello" or "Goodbye".

Try this to produce the output you desire:

#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
    cout << left << setw(10) << "Hello" << "World\n";
    cout << left << setw(10) << "Goodbye" << "World\n";
}

Upvotes: 5

Related Questions