C++ Alignment When Printing Cout ≪≪

How to Align text to the right using cout?

You need to read s line by line, then output each line right aligned.

#include <iostream>
#include <iomanip>
#include <sstream>

void printRightAlignedLines(const std::string& s, int width)
{
std::istringstream iss(s); //Create an input string stream from s
for (std::string line; std::getline(iss, line); ) //then use it like cin
std::cout << std::setw(width) << line << '\n';
}

int main()
{
std::string s = "i am\ngoing\nto\ncuet";
printRightAlignedLines(s, 75);
}

How to align output?

In your suggested code:

    cout<<a[x]<<setw(5)<<"|"<<setw(5)<<b[x]<<endl;

you have two problems that are leading to misalignment. (1) you have not provided any width for a[x] so it will be output without any adjustment; and (2) depending on the alignment you seek, the default justification when a width is specified for std::cout will be right justified.

(additionally, as noted in my comment, in your first example, a[0] and a[1] cannot have the same length as the example suggests. There "frd " is stored with additional whitespace (or "asd\b" is stored with an embedded backspace) otherwise the output of "a[x]|" would be aligned.)

To provide alignment for the output of both a and b, you must specify, at minimum, the width of a[x] with std::setw(n). Further, unless you want a[x] aligned to the right of the field created by std::setw(5), you must control the justification by setting std::ios_base::fmtflags with std::setiosflags(std::ios_base::left) (or simply std::left). See std::setiosflags.

When you set a format flag for the stream, you are setting bits in a Bitmap type that will remain set after the current call to std::cout completes. So to tidy up after yourself and restore the flag state of the stream to default, you either (1) have to save the fmtflags for the stream with by capturing all flags with std::ios_base::fmtflags or (2) you must reset the individual flag you set with std::resetiosflags(...).

So if I understand your question and your request for alignment (though it is unclear how you want b[x] aligned), you could align both a and b with left justification by:

    std::cout << "left justified output (both a & b)\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << b[i] << '\n';

or you could align a with left justification and then restore the default flag state letting b be output with default (right) justification, e.g.

    std::cout << "\nleft justified output for a, default for b\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << std::resetiosflags(std::ios_base::left)
<< std::setw(5) << b[i] << '\n';

Putting that altogether in an example, you could do:

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>

int main (void) {

std::vector<std::string> a = { "frd", "asdfg", "asd", "quack" },
b = { "hehe", "hohoo", "haloo", "hack" };

std::cout << "left justified output (both a & b)\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << b[i] << '\n';

std::cout << "\nleft justified output for a, default for b\n\n";
for (size_t i = 0; i < a.size(); i++)
std::cout << std::left << std::setw(5)
<< a[i] << " | " << std::resetiosflags(std::ios_base::left)
<< std::setw(5) << b[i] << '\n';
}

Example Use/Output

$ ./bin/setwstring
left justified output (both a & b)

frd | hehe
asdfg | hohoo
asd | haloo
quack | hack

left justified output for a, default for b

frd | hehe
asdfg | hohoo
asd | haloo
quack | hack

Note: if you want to make multiple changes to flags within the course of an output operation and then restore ALL format flags to their original state, you can use:

    std::ios_base::fmtflags f = std::cout.flags (); // save ios_base flags
// do output, set flags as desired
std::cout.flags (f); // restore saved flags

Let me know if this addresses the alignment you were attempting to achieve.

Aligning output on the right in c++

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:

AAAAAAAAAABBBB
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....BBBB
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.

C++ iomanip Alignment

If this is what you want

Sample Image

#include <iomanip>
using std::setw;
using std::right;
using std::left;

//Movie Struct to hold movie data
struct MOVIES
{
string Title; //Name of movie
int CriticRating; //Critic rating 1-100
int AudRating; //Audiences' rating 1-100
};
MOVIES Movies[10] = { { "The Wizard of Oz", 99, 70 },
{ "The Third Man", 78, 45 },
{ "Citizen Kane", 86, 85 },
{ "Charlie Chaplin in Modern Times", 56, 95 },
{ "All About Eve", 78, 94 },
{ "The Cabinet of Dr. Caligari", 76, 90 },
{ "The God Father", 99, 98 },
{ "E.T. The Extra-Terrestrial", 98, 71 },
{ "The Beatles: A Hard Day's Night", 87, 90 },
{ "Monty Python and the Holy Grail", 100, 100 }
};


void PrintMovies(MOVIES* movies, int numMovies)
{
cout << " Critic " << setw(6) << " Audience " << setw(0) << " Title " << endl;

for (int i = 0; i < numMovies; i++)
{
cout << setw(7) << right << movies[i].CriticRating << setw(10) << right << movies[i].AudRating <<" "<< setw(30) << left << movies[i].Title << endl;
}
}

int main()
{
PrintMovies(Movies, 10);

return 0;
}

Use cout to print a number in a certain format (left align & right align)

std::setiosflags() sets new flags without clearing any existing flags. So on the 3rd line, you are enabling the ios::left flag without disabling the ios::right flag. It does not make sense to have both flags enabled at the same time, and it seems the stream prefers the ios::right flag if it is enabled.

Use std::left and std::right instead. They reset the ios::internal, ios::left, and ios::right flags before setting the new alignment.

int a = 123456;
cout << setw(20) << right << a << endl;
cout << left << setw(20) << a << '*' << endl;

Live demo

Right Justifying output stream in C++

You need to use std::setw in conjunction with std::right.

#include <iostream>
#include <iomanip>

int main(void)
{
std::cout << std::right << std::setw(13) << "foobar" << std::endl;
return 0;
}

cout setw doesn't align correctly with åäö

Along with imbuing std::wcout with the proper locale, you probably have to switch to wide strings as well. For example:

void p(std::wstring s, int w)
{
std::wcout << std::left << std::setw(w) << s;
}

int main(int argc, char const *argv[])
{
setlocale(LC_ALL, "en_US.utf8");
std::locale loc("en_US.UTF-8");
std::wcout.imbue(loc);

p(L"COL_A", 7);
p(L"COL_B", 7);
p(L"COL_C", 5);
std::wcout << std::endl;
p(L"ABC", 7);
p(L"ÅÄÖ", 7);
p(L"ABC", 5);
std::wcout << std::endl;
return 0;
}

Demo

Absolute positioning in printout with cout in C++?

You use the "left" and "right" manipulators:

cout << std::left  << std::setw(30) << "This is left aligned"
<< std::right << std::setw(30) << "This is right aligned";

An example with text + numbers:

typedef std::vector<std::pair<std::string, int> > Vec;
std::vector<std::pair<std::string, int> > data;
data.push_back(std::make_pair("Alan Turing", 125));
data.push_back(std::make_pair("Ada Lovelace", 2115));

for(Vec::iterator it = data.begin(), e = data.end(); it != e; ++it)
{
cout << std::left << std::setw(20) << it->first
<< std::right << std::setw(20) << it->second << "\n";
}

Which prints:

Alan Turing                          125
Ada Lovelace 2115


Related Topics



Leave a reply



Submit