What is the easiest way code parsing string input like the following:
WORD WORD2
WORD3 WORD4
WORD5
WORD6
That is, an unknown number of pairs of words followed by a blank line followed by an unknown number of words one-per line. I want to put the first group of these words into a map, and the second list of words into a vector.
Using getline has problems discovering when the first group of paired words terminates.
A simple matter of using getline and some containers:
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <map>
std::map<std::string, std::string> m;
std::vector<std::string> v;
for (std::string line; std::getline(std::cin, line); )
{
if (line.empty()) { break; }
std::string x, y;
std::istringstream iss(line);
if (!(iss >> x >> y >> std::ws)) { /* fatal error */ }
m[x] = y;
}
for (std::string line; std::getline(std::cin, line); )
{
v.push_back(std::move(line));
}
std::cout << "We read " << m.size() << " pairs and " << v.size() << " words.\n";
If you want to make sure that the first part of the file consists precisely of pairs of words with a single region of whitespace in between, you can strengthen the condition to this:
if (!(iss >> x >> y >> std::ws) || iss.get() != EOF) { /* fatal error */ }
Similarly, you can add a check that the second part of the file contains no whitespace if you like. Finally, you could use insert() for the map to check that there are no duplicate keys; in C++11, you should be able to say m.emplace(std::move(x), std::move(y));. And an unordered_map is probably a lot more efficient with strings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With