1

I am trying to read through a text file that can possibly look like below.

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, the first word would be the key and second word would be the value.

below is the code I came up with but I can't figure out how to ignore the lines that do not have two words on them.

  • this only works properly if every line has two words. I understand why this is only working if every line has two words but, I'm not sure what condition I can add to prevent this.

pair myPair; map 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;
}
Chris
  • 71
  • 7
  • 3
    Recommended reading: [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – user4581301 Feb 13 '19 at 05:58
  • 2
    read one word, if it fails do not add. Read a second word. If it fails, do not add. Read a third word. If it *succeeds*, do not add. That should leave you with adding only if you read two words. – user4581301 Feb 13 '19 at 06:00
  • 1
    `'\0'` is not the correct delimiter to use here. Are you sure this code is working as is? – n. 'pronouns' m. Feb 13 '19 at 06:19

3 Answers3

4

Read two words into a temporary pair. If you can't, do not add the pair to the map. If you can read two words, see if you can read a third word. If you can, you have too many words on the line. Do not add.

Example:

while(getline(file2, line, '\0'))
{
    stringstream ss(line);
    pair<string,string> myPair;
    string junk;
    if (ss >> myPair.first >> myPair.second && !(ss >> junk))
    { // successfully read into pair, but not into a third junk variable
        myMap.insert(myPair);
    }
}
user4581301
  • 29,019
  • 5
  • 26
  • 45
3

let me suggest a little different implementation

std::string line;
while (std::getline(infile, line)) {
    // Vector of string to save tokens 
    vector <string> tokens; 

    // stringstream class check1 
    stringstream check1(line); 

    string intermediate; 

    // Tokenizing w.r.t. space ' ' 
    while(getline(check1, intermediate, ' ')) { 
        tokens.push_back(intermediate); 
    }

    if (tokens.size() == 2) {
        // your condition of 2 words in a line apply
        // process 1. and 2. item of vector here
    }
}
skratchi.at
  • 1,126
  • 5
  • 19
1

You can use fscanf for take input from file and sscanf for take input from string with format. sscanf return how many input successfully take with given format. so you can easily check, how many word have a line.

#include<stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;

int main()
{
    char line[100];
    FILE *fp = fopen("inp.txt", "r");
    while(fscanf(fp, " %[^\n]s", line) == 1)
    {
        cout<<line<<endl;
        char s1[100], s2[100];
        int take = sscanf(line, "%s %s", s1, s2);
        cout<<take<<endl;
    }
    return 0;
}