0

「emiltytaco 56」などの名前とグレードの .txt ファイルがあります。姓の後に、トライ アンド ヒープに挿入してはならない空白行が 3 行あります。ただし、空白行に到達すると、コードは中止され、ダンプされます。これが挿入機能です

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();

.close は、if を使用した「else」ステートメントの一部にする必要がありますか? 私の友人はまさにこれを持っていますが、彼は中絶しません。

4

1 に答える 1

1

まず、ループを次のように変更します。

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

次に、行全体を文字列ストリームにフィードし、そこから両方の部分を読み取る方がおそらくはるかに簡単です。

stringstream convert(line);

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

第三に、小文字をチェックしたい場合は、islower96や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。ストリームからを正常に読み取って変換できるかどうかをチェックするだけで、空白行では失敗します。

于 2013-02-21T04:43:36.017 に答える