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.