How to remove extra space created when using setw in C++? - c++

I am attempting format the output of a file using setw with no success. I understand that my output is shifting based on the character length of the variable before it, however I do not know how to change my code so that each row will print independent of the row before it. (Please see image link)
Due to the word "Swimming" being longer than all other word types, this shifts the information for those columns, making the report look terrible. Additionally, it seems like the comma in the "Amount" Column is shifting the output as well.
fout << s.getID()
<< right << setw(11) << addCommas(s.getAmount()) << "\t"
<< left << setw(14) << s.getType() << "\t"
<< left << setw(14) << s.getLength() << "\t"
<< left << setw(10) << s.getDate() << " "
<< left << setw(15) << s.getFname() << "\t"
<< s.getLname() << endl;
lineCount++;
Current Program Output
(Currently messing with those setw values so please disregard that they don't line up with the header at the moment)
EDIT: Changed my font in VS to Helvetica because Consolas hurts my eyes, this also affected the output of my .dat, so essentially this was a non-issue. Yikes.

If you add std::internal to your std::cout statement, it'll pump the remaining spaces out, and you can do a new setw after that. This might work better than tabs for you, especially if you're not using a monospaced font. See an example in this answer. Make sure your setw is large enough to accommodate your largest words... and don't do using namespace std, it's poor practice. Shame on you! ;)

Related

I want to use cout more comfortably

I want to use cout to print out this sentence: "You can build piramid which floor is only odd. not even", but I want to do it more comfortably. Just like the way below. But, when I use this way, an error occurs. So, is there any way to use it like this?
cout << "You can build piramid which floor is only odd.
not even" << '\n';
Adjacent string literals will automatically be concatenated, even if they are on different lines. So you can write it this way instead:
std::cout << "You can only build pyramids whose floor is odd, "
"not even.\n";
To use multi-line strings in C++, you can use backslash.
cout << "You can build piramid which floor is only odd. \
not even" << '\n';

fstream and setw not aligning output properly

setw does not seem to be aligning things here for me, and I can't figure out why that is. Inserting \t does push things to the right, but I'd like to have tighter control over the formatting of the output. Any ideas?
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
string name = "Name LastName";
int age = 27;
double milesRun = 15.5;
ofstream outFile;
outFile.open("text.txt");
outFile << "Person's name: " << name << setw(12) << "Person's age: " << age << setw(12) << "Miles run: " << milesRun << endl;
outFile.close();
return 0;
}
Remember that when using setw, the function is used to declare the area that is about to appear. Therefore, you can use it to declare static values, such as the text in your information like "Person's Name:" by counting the characters and using that as your value (generally +1 or 2). Using that as an example, the value would be setw(16) to account for each character + 2 spaces. Then you apply another setw value to declare the field to come, choosing a value large enough to accommodate your data. Remember to align left so you can see how this affects your output. In your example, you were aligning right, and while that may give formatted output in some examples, it breaks in others, as you saw.
If you want more space between each data set, then simply increase the width of the field like in this example. This way everything is left aligned and you have no need for tabs.

Output of the cout changes according to typecasting way

I'm working on a program and have a strange, cout related problem. Since the program is a bit big and the code talks best, I'll paste the relevant snippets.
First, I have an iterator, *it defined in a for as
for(vector<facet*>::iterator it=facets_to_dump->begin(); it<facets_to_dump->end(); it++)
In this for, if I use the expression
facet* facet_to_work_on = *it;
cout << facet_to_work_on->facet_id << "\t";
Nicely prints out integers.
But, if I use the notation
cout << (facet*)(*it)->facet_id << "\t";
This code prints out hex values. Hex values are equal to the integer values. Any idea why this is happening?
Thanks in advance.
The reason
cout << (facet*)(*it)->facet_id << "\t";
prints out a hex value is that -> binds harder than the (facet*) cast, that is it evaluates
(*it)->facet_id
and casts the result to a facet*. Pointers are output in hex.
Try including <iomanip> and:
cout << dec << (facet*)(*it)->facet_id << "\t";
To say you want numbers in decimal form.

Right Justifying output stream in C++

I'm working in C++. I'm given a 10 digit string (char array) that may or may not have 3 dashes in it (making it up to 13 characters). Is there a built in way with the stream to right justify it?
How would I go about printing to the stream right justified? Is there a built in function/way to do this, or do I need to pad 3 spaces into the beginning of the character array?
I'm dealing with ostream to be specific, not sure if that matters.
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;
}
Yes. You can use setw() to set the width. The default justification is right-justified, and the default padding is space, so this will add spaces to the left.
stream << setw(13) << yourString
See: setw(). You'll need to include <iomanip>.
See "setw" and "right" in your favorite C++ (iostream) reference for further details:
cout << setw(13) << right << your_string;
Not a unique answer, but an additional "gotcha" that I discovered and is too long for a comment...
All the formatting stuff is only applied once to yourString. Anything additional, like << yourString2 doesn't abide by the same formatting rules. For instance if I want to right-justify two strings and pad 24 asterisks (easier to see) to the left, this doesn't work:
std::ostringstream oss;
std::string h = "hello ";
std::string t = "there";
oss << std::right << std::setw(24) << h << t;
std::cout << oss.str() << std::endl;
// this outputs
******************hello there
That will apply the correct padding to "hello " only (that's 18 asterisks, making the entire width including the trailing space 24 long), and then "there" gets tacked on at the end, making the end result longer than I wanted. Instead, I wanted
*************hello there
Not sure if there's another way (you could simply redo the formatting I'm sure), but I found it easiest to simply combine the two strings into one:
std::ostringstream oss;
std::string h = "hello ";
std::string t = "there";
// + concatenates t onto h, creating one string
oss << std::right << std::setw(24) << h + t;
std::cout << oss.str() << std::endl;
// this outputs
*************hello there
The whole output is 24 long like I wanted.
Demonstration

How do I convert this C line to C++? using cout command

printf("%-8s - %s\n", c->name ? c->name : "", c->help);
I think what you're looking for is
cout << left << setw(8) << (c->name ? c->name : "") << " - " << c->help << endl;
The left and setw(8) manipulators together have the same effect as the %-8s formatting specifier in printf. You will need to #include <iomanip> in order for this to work, though, because of the use of setw.
EDIT: As Matthieu M. pointed out, the above will permanently change cout so that any padding operations print out left-aligned. Note that this isn't as bad as it might seem; it only applies when you explicitly use setw to set up some padding. You have a few options for how to deal with this. First, you could just enforce the discipline that before using setw, you always use either the left or right manipulators to left- or right-align the text, respectively. Alternatively, you can use the flags and setf function to capture the current state of the flags in cout:
ios_base::fmtflags currFlags = cout.flags();
cout << left << setw(8) << (c->name ? c->name : "") << " - " << c->help << endl;
cout.setf(currFlags, ios_base::adjustfield);
This works in three steps. The first line reads the current formatting flags from cout, including how it's currently aligning padded output. The second line actually prints out the value. Finally, the last line resets cout's output flags for internal alignment to their old value.
Personally, I think the first option is more attractive, but it's definitely good to know that the second one exists since it's technically more correct.
If you've got the Boost libraries:
std::cout << boost::format("%-8s - %s\n") % (c->name ? c->name : "") % c->help;