Paring string's from a file into a map

I'm fairly new to c++ and definitely hit a road block. Please bare with me. I'm trying to read a file that could look like so...

HI bye
goodbye

foo bar
boy girl
one two three

I am trying to take the lines with only two words and store them in a map, first word is the key and second word is the value.

below is the code I came up with but I can't figure out how to ignore the lines without two words..

- this only works properly if every line has two words.
pair<string, string> myPair;
map<string, string> myMap;

while(getline(file2, line, '\0'))
{
stringstream ss(line);
string word;
while(!ss.eof())
{
ss >> word;
myPair.first = word;
ss >> word;
myPair.second = word;

myMap.insert(myPair);
}
}

map<string, string>::iterator it=myMap.begin();

for(it=myMap.begin(); it != myMap.end(); it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
Last edited on
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
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
    // Using this for testing.
    istringstream in(
        "HI bye\n"
        "goodbye\n"
        "\n"
        "foo bar\n"
        "boy girl\n"
        "one two three\n");

    string line;
    while (getline(in, line))  
    {
        istringstream iss(line);
        string word1;
        if (!(iss >> word1))
            continue;  // line had no words
        string word2;
        if (!(iss >> word2))
            continue;  // line only had one word
        string word3;
        if (iss >> word3)
            continue;  // line had more than two words

        // Line had exactly two words.
        cout << word1 << ", " << word2 << '\n';
    }
}

chris2013.dat:
1
2
3
4
5
6
HI bye
goodbye

foo bar
boy girl
one two three


Hints:
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
42
43
44
45
46
47
48
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <sstream>
#include <string>
#include <vector>


std::map<std::string, std::string> readMap(std::ifstream& fin);
void displayMap(const std::map<std::string, std::string>& m);


int main()
{
    std::string fname { "chris2013.dat" };
    std::ifstream fin(fname);
    if(!fin) {
        std::cout << "cannot open " << fname << ".\nExiting now.\n";
        return 0;
    }

    auto words { readMap(fin) };
    displayMap(words);
}


std::map<std::string, std::string> readMap(std::ifstream& fin)
{
    std::map<std::string, std::string> mymap;
    for(std::string line; std::getline(fin, line); /**/) {
        std::istringstream iss { line };
        std::vector<std::string> v ( std::istream_iterator<std::string> { iss },
                                     std::istream_iterator<std::string> {} );
        if(2 == v.size()) {
            mymap.insert( {v.at(0), v.at(1) } );
        }
    }
    return mymap;
}


void displayMap(const std::map<std::string, std::string>& m)
{
    for(const auto& e : m) {
        std::cout << e.first << ' ' << e.second << '\n';
    }
}


Output:
HI bye
boy girl
foo bar


Please note that if two lines begin by the same word, e.g.
foo bar
foo pub

the second one will be neglected. Maybe you want to use a std::multimap instead?
Topic archived. No new replies allowed.