user3011154
user3011154

Reputation: 11

read two columns from a text file

string dictionary;
ifstream in;
in.open("Q3.dic");
while(!in.eof())
{
    getline(in, dictionary);
    cout << dictionary <<endl;
}

This is what I'm using to read a text file which looks like this:

you     vous
today       aujourd'hui
good        bon
good morning    bonjour
afternoon   après-midi
good evening    bonsoir
much        beaucoup
is      est

Note: The English phrase is separated from its French translation by a tab character.

What I what to know is, is it possible to instead read each column to two different variables?

I tried:

in >> english >> french;
cout << english << french <<endl;

But the problem I ran into was the rows with three words.

Upvotes: 1

Views: 3788

Answers (2)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

I think you want to use something like a std::map<std::string,std::string>, where yo have one word as key for a specific language (please read explanations from the comments):

std::map<std::string,std::string> dictionary;
ifstream in;
in.open("Q3.dic");

std::string line;
while(getline(in, line)) { // Read whole lines first ...
    std::istringstream iss(line); // Create an input stream to read your values
    std::string english; // Have variables to receive the input
    std::string french;  // ...
    if(iss >> english >> french) { // Read the input delimted by whitespace chars
        dictionary[english] = french; // Put the entry into the dictionary.
                                      // NOTE: This overwrites existing values 
                                      // for `english` key, if these were seen
                                      // before.
    }
    else {
       // Error ...
    }
}

for(std::map<std::string,std::string>::iterator it = dictionary.begin();
    it != dictionary.end();
    ++it) {
    std::cout << it->first << " = " << it->second << std::endl;
}

See a Live Working Sample of the code.


Upon my note in the code comments, you may have noticed it might be necessary to handle non unique english -> french translations. There are cases where one english keyword in the dictionary may have more than one associated translations.

You can overcome this either declaring your dictionary like this

std::map<std::string,std::set<std::string>>> dictionary;

or

std::multi_map<std::string,std::string> dictionary;

Upvotes: 1

johnsyweb
johnsyweb

Reputation: 141810

std::getline() accepts a third argument - delim - the delimiter character, if you specify it as '\t' (tab) for the first call, you should get the results you desire:

std::ifstream in("Q3.dic");

for (std::string english, french;
    std::getline(in, english, '\t') && std::getline(in, french);
    )
{
    std::cout << "English: " << english << " - French: " << french
        << std::endl;
}

For those lines containing multiple tabs, you'll need to trim the string, but I'm declaring that to be outside the scope of this question!

Output:

English: you - French:  vous
English: today - French:        aujourd'hui
English: good - French:         bon
English: good morning - French: bonjour
English: afternoon - French: après-midi
English: good evening - French: bonsoir
English: much - French:         beaucoup
English: is - French:   est

Upvotes: 3

Related Questions