Reputation: 849
I want read a file where there are the names of AC Milan's players and their date of birth. I want display this in two aligned columns. I tried to use setw() and left but the result isn't what I want. This is the code that I used for read and print:
void read(char filename[]){
fstream mio_file;
char c;
bool start_name = true;
bool start_date = true;
mio_file.open(filename, ios_base::in | ios_base::binary);
mio_file.read(&c, sizeof(char));
while(!mio_file.eof()){
if(c >= 'A' && c <= 'z' && start_name){
cout << endl << "Name : ";
start_name = false;
start_date = true;
}
if(c >= '0' && c <= '9' && start_date){
cout << setw(25) << left << "Date of birth : ";
start_date = false;
start_name = true;
}
cout << c;
mio_file.read(&c, sizeof(char));
}
mio_file.close();
}
This is output :
And this is output that I want :
Upvotes: 1
Views: 21518
Reputation: 385405
(N.B. I'm guessing at your input data, which you did not provide.)
You put setw
in the wrong place.
It goes before the thing you're columnising, not afterwards. (This is because the manipulator needs to start counting characters in order to make it work.)
So, instead of (example):
cout << setw(25) << left << "Date of birth : ";
try (example):
cout << endl << "Name : " << setw(25) << left;
Now the stream is set up to treat the next insertion (i.e your. cout << c
) as columnar, left-aligned with width 25.
Unfortunately, you're reading individual characters at a time, so your IO manipulator is never going to work on the full name; only individual characters.
So you're also going to have to do some buffering before you feed cout
with full strings (example):
std::string token;
mio_file.read(&c, sizeof(char));
while(!mio_file.eof()){
if (c >= 'A' && c <= 'z' && start_name) {
cout << token;
cout << endl << "Name : " << setw(25) << left;
token = "";
start_name = false;
start_date = true;
}
if (c >= '0' && c <= '9' && start_date) {
cout << token;
cout << "Date of birth : ";
token = "";
start_date = false;
start_name = true;
}
token += c;
mio_file.read(&c, sizeof(char));
}
// Final write
cout << token;
I'm sure there's a better way of implementing this loop, though.
Upvotes: 1
Reputation: 15541
You need to use the std::setw for each of the columns. Not just set it once. Example:
std::cout << std::left << std::setw(25) << "Column 1" << std::setw(25) << "Column 2" << std::endl;
In your particular case you only need to apply it on the Name column:
std::cout << std::left << std::setw(25) << "Name : ";
Upvotes: 4