1
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.

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
user3011154
  • 11
  • 1
  • 2
  • you'll need something to denote where the english words stop and french ones start otherwise it will be difficult to fix your 3 word problem – nick Mar 31 '14 at 20:56
  • Yes, you can read each column to different variables but you'll need some type of delimiter to separate English and French words – ovaltein Mar 31 '14 at 20:57
  • You're loop condition might cause you trouble later on if it doesn't do so already, see: [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/q/5605125) – AliciaBytes Mar 31 '14 at 20:57
  • You can use "tab" as delimiter and read english and french words in different variables. – Vishal R Mar 31 '14 at 20:58
  • If I understand the format correctly, the simplest way would probable be to read the whole line, search for more than one space in a row, and then use everything before that as English, and everything after as French. – celtschk Mar 31 '14 at 21:03

2 Answers2

3

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
Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
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;
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190