Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aligning output on the right in c++

Tags:

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?

like image 290
user3340001 Avatar asked Apr 10 '14 07:04

user3340001


2 Answers

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.

like image 143
Flovdis Avatar answered Oct 04 '22 06:10

Flovdis


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";
}
like image 39
Gassa Avatar answered Oct 04 '22 05:10

Gassa