Reputation: 237
#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
Reputation: 562
try this -
cout << right << "Hello" << "\t" << "World\n";
cout << right << "Goodbye" << "\t" << "World\n";
Upvotes: 0
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
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;
}
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
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