Reputation: 1
My first problem is if I'm even reading the components of the file into the array correctly. Then I need to display the array like the file with row and column indicators. I thought I was close but I can't get the indicators to display properly and the contents of the array don't seem to be displaying properly. I'm still new to c++ so this has been difficult for me.
Here's the input file:
X X X X X
X X X X X
X X X X X
O O O O O
O O O O O
O O O O O
O O O O O
O O O O O
O O O O O
O O O O O
O O A A A
O O A A O
O A A O O
X X X X X
O O O O O
O A A O O
O A A O O
O O A O O
O A O O O
O O A O O
O A O O O
O O A A A
O O O O O
O O O O O
A A A A O
O A O O O
A A A A A
A A A A A
A A A A A
O A O O O
O O A O O
O O A O O
X X A A O
A A A A O
A A A A A
A A A A A
O O A A A
X X A A A
And here's the code I have so far (With some unnecessary stuff removed):
string origin, destination, airplane;
int month, day, year, seat, option;
char seats[5][38];
ifstream infile;
ifstream outfile;
cout << "\nPlease enter the airplane you wish to board: ";
cin >> airplane;
cout << "\nWould you like to: \n1) Pick your own seat \n2)Let to program pick your seat" << endl;
cin >> option;
airplane.insert(4, ".txt");
infile.open(airplane.c_str());
if (infile.fail())
{
cout << airplane << " does not exist." << endl;
return 0;
}
while (!infile.eof())
{
for (int i = 0; i < 5; i++)
for (int j = 0; j < 38; j++)
infile >> seats[i][j];
}
switch (option)
{
case 1:
{
cout << "\tA C D E F" << endl;
for (int row = 0; row < 5; row++)
for (int col = 0; col < 38; col+=5)
cout << seats[row][col] << " " << seats[row][col+1] << " " << seats[row][col+2] << " " << seats[row][col+3] << " " << seats[row][col+4] << endl;
cout << "\n";
break;
}
}
return 0;
}
Upvotes: 0
Views: 37
Reputation: 117433
The way you read from the file is almost always wrong:
while (!infile.eof())
The problem is that infile.eof()
will not return true
until it's actually tried to read passed the last character in the file, so you'll get one extra iteration in the while
loop which means that the below part will be executed twice:
for (int i = 0; i < 5; i++)
for (int j = 0; j < 38; j++)
infile >> seats[i][j];
I suggest separating the stream I/O from the rest of the logic. You could define a Row
that only holds the seats for one row:
struct Row {
char seats[5];
};
With that, add overloads for operator>>
and operator<<
to read/write one Row
from/to streams:
// Read one Row from an `istream`, like your `infile`:
std::istream& operator>>(std::istream& is, Row& r) {
for(char& seat : r.seats) is >> seat; // a range-based for loop
return is;
}
// Write one Row to an `ostream`, like `std::cout`
std::ostream& operator<<(std::ostream& os, const Row& r) {
return os
<< r.seats[0] << ' ' << r.seats[1] << " "
<< r.seats[2] << ' ' << r.seats[3] << ' ' << r.seats[4];
}
Reading from infile
to fill an array of Row
could then look like this:
Row rows[38];
for(Row& r : rows) { // A range-based for loop again
if(!(infile >> r)) { // check that extracting the Row suceeds
std::cout << "aircraft file corrupted\n";
return 1;
}
}
Writing the result to screen (requires #include <iomanip>
for std::setw()
):
std::cout << " A C D E F\n";
for(size_t idx = 0; idx < std::size(rows); ++idx) {
std::cout << std::setw(2) << idx+1 << ' ' << rows[idx] << '\n';
}
Upvotes: 1