从.txt读入

时间:2013-02-21 03:48:33

标签: c++ heap abort

我有一个.txt文件,其名称和等级如“emiltytaco 56”。在姓氏之后,有3个空白行不应该插入我的trie和堆中。但是,当命中空行时,代码将被中止并转储。这是插入函数

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”语句的一部分吗?我的一个朋友有这个确切的事情,但他不会中止。

1 个答案:

答案 0 :(得分:1)

首先,将你的循环改为:

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

其次,将整行馈送到stringstream可能要简单得多,并从那里读取两个部分:

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";
    }

除此之外还有一个步骤:由于名称和等级(显然)相关,我可能会为它们定义一个类,并编写一个提取器以从流中获取该类型的对象:

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,这将失败空行。