8
#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?

4 Answers 4

9

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.

Sign up to request clarification or add additional context in comments.

12 Comments

@AlexanderTobiasHeinrich Sorry, I copied the wrong example. Now it's fixed and works as expected.
@Flovdis Why should one avoid using using namespace std ?
What if the cout was like cout << "hello" << " world " << " today\n"; and you wanted to right justify today?
@user3340001 In this case just put the operators before the "today" string. All operators are applied to all following values in the stream.
@user3340001 Or probably I misunderstand your question. Can you explain what you mean with "right justified"?
|
5

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"; } 

Comments

2

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"); } 

2 Comments

Unfortunately only MSVC >=19.29 currently supports std::format by default, according to cppreference. Here is a running example. Oh, and of course in thge meantime fmt::print is also possible... Anyhow, +1 for providing a modern solution as alternative :-)
cppreference is not always up to date. All major standard libraries support std::format: stackoverflow.com/questions/63724059/…
0

try this -

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.