0

I have a .txt file with names and grades such as "emiltytaco 56". After the last name, there are 3 blank lines which should not be inserted into my trie and heap. However the code is Aborted and dumped when hitting the blank lines. This is the insert function

while(myfile.good())
{
    getline(myfile, line);
    name = line.substr(0,line.find("\t"));
    stringstream convert((line.substr(line.find("\t")+1)));
    convert >> grade;  
    if(name.at(0) > 96 && name.at(0) < 123)
    {
        insert(name, grade);
        cout << name << "   " << grade << endl;
    }
}
myfile.close();

should the .close be part of an "else" statement with the if? a friend of mine has this exact thing but his does not abort.

trincot
  • 317,000
  • 35
  • 244
  • 286
emelton22
  • 18
  • 1

1 Answers1

1

First point, change your loop to something like:

while (getline(myfile, line)) {
    // ...
}

Second, it's probably a lot simpler to feed the whole line to the stringstream, and read both pieces from there:

stringstream convert(line);

std::getline(convert, name, '\t');
convert >> grade;

Third, if you want to check for lower-case letters, you're much better off with islower than comparisons to magic numbers like 96 and 123. I wouldn't do the check that way though. If you want to check for a blank line, it would be better to do that directly, with line.empty() immediately after you read it. Using that, you end up with something like:

while (getline(myfile, line))
    if (!line.empty()) {
        std::istringstream convert(line);
        std::getline(convert(line, name);
        convert >> grade;
        insert(name, grade);
        std::cout << name << "    " << grade << "\n";
    }

There is one more step beyond that though: since the name and grade are (apparently) related, I'd probably define a class for them, and write an extractor to get an object of that type from a stream:

class whatever { 
    std::string name;
    int grade;

    friend std::istream &operator>>(std::istream &is, whatever &w) { 
        std::getline(is, w.name, '\t');
        is >> w.grade;
        is.ignore(4096, '\n');
        return is;
    }
};

With that in place, we can read the data from the file quite a bit more simply:

whatever w;

while (myfile >> w) {
    insert(w);
    std::cout << w.name << "    " << w.grade << "\n";
}

Note that in this case, we don't have to check for the blank lines explicitly at all -- we just check whether we could successfully read and convert a whatever from the stream, which will fail for a blank line.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111