Alas, your textbook/website/teacher has failed you badly here. Just about everything in that is wrong. (Sorry!)
Here you go (compile with C++17 enabled):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#include <ciso646>
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
// Helpful type alias
typedef std::unordered_multimap <std::string, std::string> Routes;
// Helpful function
std::string trim( const std::string& s )
{
auto n = s.find_first_not_of( " \t" );
if (n == s.npos) return "";
return s.substr( n, s.find_last_not_of( " \t" ) + 1 - n );
}
int main()
{
Routes requestedRoutes;
{
std::ifstream f{ "requestFile.txt" };
while (true)
{
std::string originCity;
if (!getline( f, originCity, ',' )) break;
std::string destinationCity;
if (!getline( f, destinationCity )) break;
if (trim( originCity ).empty() or trim( destinationCity ).empty()) continue;
requestedRoutes.emplace( trim( originCity ), trim( destinationCity ) );
}
}
// Tada! Now you have an origin→destination city mapping.
// Let’s print it out just for kicks:
for (auto [originCity, destinationCity] : requestedRoutes)
std::cout << trim( originCity ) << ", " << trim( destinationCity ) << "\n";
}
|
The important parts are:
• Have a definite structure to store your cities.
I used a multimap, which is designed exactly for these kinds of problems.
• Keep your file streams as local objects in a local block. (Notice the curly braces.)
When the file stream goes out of scope it will close automatically.
• Don’t bother testing if the file is open. All I/O will fail if it is not open.
• Don’t loop on EOF. This will get you a failure result in your list. Why?
Because you did not test for failure immediately after an attempted read. Which leads us to:
• Always test for failure after an attempted read. Since we are attempting to read TWO
things with getline, and to better illustrate what is happening, I put both read attempts
inside the loop and tested immediately for termination.
• Only AFTER failure has NOT occurred do we mess with the extracted value(s).
So the basic construct is:
1 Try to get originCity, bail if stream failure (due to EOF, probably)
2 Try to get destinationCity, bail if stream failure (due to EOF, probably)
3 Check that both cities are valid (not empty strings)
4 Add the cities to the requestedRoute mapping
Hope this helps.