As mentioned in comments, the setw
manipulator only applies to the next string, so
cout << left << setw(15) << "{" << days[0] << ", " << days[1] << ", " << days[2];
will set a width of 15 only for the character {
(similarly in the line with "First Name: "
, etc.). It is also worth noting that if a string exceeds the specified width, then it will push the next contents and break the alignment of your columns; so you need to set the width thinking about the largest possible contents.
Here is a working example to implement what you want, using a stringstream
to form the string before printing it (in order for setw
to apply to the entire thing):
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
// ------------------------------------------------------------------------
struct Student
{
std::string ID, First, Last, Email, Degree;
unsigned age;
std::vector<unsigned> days;
Student( std::string ID, std::string First, std::string Last, unsigned age,
std::string Email, std::string Degree, std::vector<unsigned> days )
: ID(ID), First(First), Last(Last), age(age), Email(Email), Degree(Degree), days(days)
{}
};
std::ostream& operator<< ( std::ostream& os, const Student& s ) {
std::ostringstream ss;
ss << "First Name: " << s.First;
os << std::left << std::setw(25) << ss.str();
ss.str("");
ss << "Last Name: " << s.Last;
os << std::left << std::setw(35) << ss.str();
ss.str("");
ss << "Email: " << s.Email;
os << std::left << std::setw(50) << ss.str();
ss.str("");
ss << "Age: " << s.age;
os << std::left << std::setw(10) << ss.str();
ss.str("");
ss << "{" << s.days.at(0) << ", " << s.days.at(1) << ", " << s.days.at(2) << "}";
os << std::left << std::setw(20) << ss.str();
ss.str("");
ss << "Degree Program: " << s.Degree;
os << std::left << std::setw(30) << ss.str();
ss.str("");
return os << std::endl;
}
// ------------------------------------------------------------------------
int main() {
std::cout << Student("A3","Robert","Smith",19,"example@foo.com","SOFTWARE",{20,40,33});
std::cout << Student("A4","Alice","Smith",22,"example@bar.net","SECURITY",{50,58,40});
}
outputs:
First Name: Robert Last Name: Smith Email: example@foo.com Age: 19 {20, 40, 33} Degree Program: SOFTWARE
First Name: Alice Last Name: Smith Email: example@bar.net Age: 22 {50, 58, 40} Degree Program: SECURITY
Note that I have set different widths for each field, depending on the expected lengths of the contents. For example, e-mail addresses can be quite long, but the age will rarely exceed two digits.