まず、ループを次のように変更します。
while (getline(myfile, line)) {
// ...
}
次に、行全体を文字列ストリームにフィードし、そこから両方の部分を読み取る方がおそらくはるかに簡単です。
stringstream convert(line);
std::getline(convert, name, '\t');
convert >> grade;
第三に、小文字をチェックしたい場合は、islower
96や123のようなマジックナンバーと比較するよりもはるかに優れています。しかし、私はそのようにチェックしません。空白行を確認したい場合は、line.empty()
読んだ直後に直接確認することをお勧めします。それを使用すると、次のような結果になります。
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";
}
ただし、それを超えるもう1つのステップがあります。名前とグレードは(明らかに)関連しているので、おそらくそれらのクラスを定義し、ストリームからそのタイプのオブジェクトを取得するためのエクストラクターを作成します。
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;
}
};
これで、ファイルからデータをかなり簡単に読み取ることができます。
whatever w;
while (myfile >> w) {
insert(w);
std::cout << w.name << " " << w.grade << "\n";
}
この場合、空白行を明示的にチェックする必要はまったくないことに注意してくださいwhatever
。ストリームからを正常に読み取って変換できるかどうかをチェックするだけで、空白行では失敗します。