fstream and setw not aligning output properly - c++

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.

Related

How to remove extra space created when using setw in 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! ;)

Is cout.put() recommended over cout<< for printing characters

Background
IIRC, from Release 2.0 C++ stores single-character constants as type char and NOT int. But before Release 2.0 a statement like
cout<<'A'
was problematic as it displays the ASCII value of 'A' ie 65 whereas:
char ch='A';
cout<<ch;
would display the right value ie 'A'.
Since the problem has been rectified in Release 2.0. I believe cout.put() lost the advantage it had over cout<<.
Question
Is there any other reason for recommending cout.put() over cout<< for printing characters?
There are a few differences between cout<< and cout.put, or should we say the overloaded << operator and the put method from std::basic_ostream because this is not really limited to the global instance: cout.
The << operator writes formatted output, the put method does not.
The << operator sets the failbit if the output fails, the put method does not.
Personally I would go with the << operator in almost all cases, unless I had specific needs to bypass the formatted output or not setting the failbit on error.
Using them can result in the following differences of output:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "Character: '" << setw(10) << 'A' << setw(0) << "'" << endl;
cout << "Character: '" << setw(10);
cout.put('A');
cout << setw(0) << "'" << endl;
return 0;
}
Outputs:
Character: ' A'
Character: 'A'
See the above in action: http://ideone.com/9N0VYn
Since the put method is unformatted it does not respect the manipulator set, there might be situations where that is indeed what you intend. But since it sounds like you only want to print out the character, I would prefer the << operator, which respects the formatting.
And then there is the case of the failbit which is not being set, and that might even be more crucial.

Decimals not displaying when using Float or Double type

My code is this:
#include <iostream>
int main()
{
using namespace std;
const float dollar = 1.00;
cout << "You have " << dollar*10.00 << " dollars." << endl;
cin.get();
cin.get();
return 0;
}
I am a beginner to c++. I typed this code just playing around and assumed that the console would display "You have 10.00 dollars, but it actually displays that I have "10" and not "10.00" dollars. Could someone tell me why this is?
Since you are dealing with dollar amounts, you can set the following before writing to cout:
std::cout.precision(2);
std::cout.setf(std::ios::fixed);
Live code example at coliru
#include <iostream>
int main() {
using namespace std;
const float dollar = 1.00;
std::cout.precision(2);
std::cout.setf(std::ios::fixed);
cout << "You have " << dollar*10.00 << " dollars." << endl;
cin.get();
cin.get();
return 0;
}
The standard library already has some code to deal with monetary values. In C++98/03, it's sufficiently painful to use that it's probably not worth the trouble, but in C++11, a couple of I/O manipulators were added that make them quite easy to use.
In the default "C" locale, they probably won't be of much use, but in a nationalized locale, they will format money as you'd normally expect for that locale. For example:
#include <iostream>
#include <iomanip>
int main(){
long double amt;
std::cin.imbue(std::locale(""));
std::cout.imbue(std::locale(""));
std::cin >> std::get_money(amt);
std::cout << std::put_money(amt) << "\n";
}
This uses the "" locale, which chooses a locale based on how the OS is configured. For example, in my case the OS is set up for US English, so that chooses the US English locale.
Based on the locale, this displays the money as (the programmers guess) money would normally be displayed in that locale. For example, if I enter "10" (with or without some 0's after the decimal point), it prints the value out as 10.00.
If I prefer, I can specify a locale--for example, I can specify "de" to get a German locale. In this case, the value will (at least with the compiler I have handy) be printed out using German conventions (. as a thousands separator and , as a decimal separator). Also note that I can specify the locale for std::cin separately from the locale for std::cout, so I can (for example) set cin to US English, and cout to German. If I do so, I can enter 1,234,567.89 as the input, and receive 1.234.567,89 as the output. (Note that although it converts the formatting from US to German convention, it does not automatically convert my input in dollars to Euros at output).
Note that put_money also automatically restores the previous formatting after it does its thing. For example, if I change the last line above to: std::cout << std::put_money(amt) << "\n";, then enter 10 as the input, I get 10.00 10.
Also note that (at least with VC++) std::get_money actually stores the value as an integer count of cents, which will prevent most rounding errors. So, if I enter 10 what's actually stored is 1000, which is then re-scaled to display as 10.00 at output.
If you're stuck with an older compiler that doesn't include std::get_money and std::put_money, it's probably easiest to just copy their definitions from the standard, put them into a header of your own, and use them anyway. If you don't want to do that, I'd consider defining a money class that stores an amount of money, and overloads operator>> and (especially) operator<< to handle formatting as you see fit, so writing out a monetary value would be something like:
money m(10);
std::cout << m;
...and the operator<< would handle all the std::setprecision and such to display that with two places after the decimal point and such.
If you don't format output, cout will cut unnecessary zeroes. You can set precision of output.
cout<<fixed<<setprecision(2)<<dollar<<endl;
//cout << setprecision(3) << fixed;
Also one more point dont put
using namespace std; inside the main statement,
Add header #include
//Code //
int main()
{
float dollar = 2.00f;
cout << setprecision(3) << fixed;
std::cout << dollar << " dollars." << endl;
cin.get();
cin.get();
return 0;
}

Output shows no zero

FYI I'm a beginner in C++. This is just a part of the complete code, the problem is the 'student.id', if the input starts with '0' e.g.'06042010', the output shows no zero(in this case would be '6042010'! And the point is, I want that first zero to be shown. Thanks.
#include<iostream>
using namespace std;
struct students
{
char name[15];
char surname[10];
int id;
};
int main()
{
students student;
cout<<"Name: ";
cin>>student.name;
cout<<"Surname: ";
cin>>student.surname;
cout<<"ID: ";
cin>>student.id;
cout<<"\nStudent: "<<student.name<<" "<<student.surname<<" ID "<<student.id<<endl;
return 0;
}
If you need to preserve leading zeros, you should store id as a string and not an int.
If your IDs will always be a particular length, you can use C's printf function instead of streams, which gives you more power;
printf( "Student: %s %s ID %08d\n", student.name, student.surname, student.id );
That will always print 8 digits of ID, and will prefix with 0s as needed (if it was just %8d it would prefix with spaces).
But as already pointed out, you're likely better off storing it as a string, because then you will be able to increase the length of the IDs in the future without needing to adjust all the old IDs.
If you need or want to keep the student id a number for some reason you can also us the following:
#include <iomanip>
const int width = 8; //The length of your student ID numbers
cout << "\nStudent: " << student.name << " " <<student.surname
<< " ID " << setfill('0') << setw(width) << student.id << setfill(' ') << endl;
If your ID numbers are not all the same length you will have to detect how long they are and use the appropriate width in each setw() call.

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