0

发生这种情况有什么原因吗?我以两个不同的名称保存了相同的文件。一个是test.csv,另一个是text.txt。内容相同。当我使用 ifstream 对象打开 text.txt 时,我的代码按预期运行并将数据解析为一个对象。当我打开 test.csv 时,我的 ifstream 对象没有收集任何数据,并且代码出现故障。打开 .csv 而不是 .txt 时,是否需要采取任何额外的步骤?

这是实际执行输入的代码:

    Team::Team(ifstream& fin)
    {
string temp;
stringstream convert;

//Get team #
getline(fin, temp, ',');
idNumber = stringToInt(temp);

//Get team letter
getline(fin, temp, ',');
idLetter = temp[0];

//Get team name
getline(fin, name, ',');

//Get team type
getline(fin, type, ',');

//Get team rating
getline(fin, temp, ',');
rating = stringToDouble(temp);

//Get team notes
getline(fin, notes, ',');

//Get toss info
getline(fin, temp, ',');
canToss = stringToBool(temp);
getline(fin, tossType, ',');

//Get female info
getline(fin, temp, ',');
hasFemales = stringToBool(temp);
getline(fin, temp, ',');
femaleNumber = stringToInt(temp);
getline(fin, temp, ',');
femaleRating = stringToDouble(temp);

//Get Auto info
getline(fin, temp, ',');
hasAuto = stringToBool(temp);
getline(fin, autoType, ',');
getline(fin, temp, ',');
autoScore = stringToInt(temp);

//Get Drive Info
getline(fin, temp, ',');
driveMotors = stringToInt(temp);
getline(fin, temp, ',');
driveRatio = stringToDouble(temp);
getline(fin, driveType, ',');

//Get hang info
getline(fin, temp, ',');
canHang = stringToBool(temp);
getline(fin, hangType, ',');

//Get stash info
getline(fin, temp, ',');
canStash = stringToBool(temp);

//Get lift indo
getline(fin, temp, ',');
liftMotors = stringToInt(temp);
getline(fin, temp, ',');
liftRatio = stringToDouble(temp);
getline(fin, liftType, ',');

//Get competition info
getline(fin, temp, ',');
driverSkills = stringToInt(temp);
getline(fin, temp, ',');
programmingSkills = stringToInt(temp);
getline(fin, temp, ',');
ranking = stringToInt(temp);
getline(fin, temp, ',');
wins = stringToInt(temp);
getline(fin, temp, ',');
ties = stringToInt(temp);
getline(fin, temp, ',');
losses = stringToInt(temp);
getline(fin, temp);
SPs = stringToInt(temp);
    }
4

1 回答 1

1

如果没有读取操作获取任何内容,则很可能是您没有成功打开文件,虽然可能有很多原因,但第一步是检测到这一点。您是否测试文件是否成功打开?你可以这样做:

if (ifstream fin("test.csv")) {
    Team team(fin);
    ⋮
} else {
    std::cerr << "Failed to open test.csv\n";
}

当我这样做时,我可以建议代码重组吗?大约 80% 的编码是维护,因此视觉处理的清晰度和速度应该是您编码风格的关键考虑因素:

getline(fin, temp     , ','); idNumber          = stringToInt   (temp);
getline(fin, temp     , ','); idLetter          = temp[0];
getline(fin, name     , ',');
getline(fin, type     , ',');
getline(fin, temp     , ','); rating            = stringToDouble(temp);
getline(fin, notes    , ',');

getline(fin, temp     , ','); canToss           = stringToBool  (temp);
getline(fin, tossType , ',');

getline(fin, temp     , ','); hasFemales        = stringToBool  (temp);
getline(fin, temp     , ','); femaleNumber      = stringToInt   (temp);
getline(fin, temp     , ','); femaleRating      = stringToDouble(temp);

getline(fin, temp     , ','); hasAuto           = stringToBool  (temp);
getline(fin, autoType , ',');
getline(fin, temp     , ','); autoScore         = stringToInt   (temp);

//Get Drive Info
getline(fin, temp     , ','); driveMotors       = stringToInt   (temp);
getline(fin, temp     , ','); driveRatio        = stringToDouble(temp);
getline(fin, driveType, ',');

//Get hang info
getline(fin, temp     , ','); canHang           = stringToBool  (temp);
getline(fin, hangType , ',');

//Get stash info
getline(fin, temp     , ','); canStash          = stringToBool  (temp);

//Get lift indo
getline(fin, temp     , ','); liftMotors        = stringToInt   (temp);
getline(fin, temp     , ','); liftRatio         = stringToDouble(temp);
getline(fin, liftType , ',');

//Get competition info
getline(fin, temp     , ','); driverSkills      = stringToInt   (temp);
getline(fin, temp     , ','); programmingSkills = stringToInt   (temp);
getline(fin, temp     , ','); ranking           = stringToInt   (temp);
getline(fin, temp     , ','); wins              = stringToInt   (temp);
getline(fin, temp     , ','); ties              = stringToInt   (temp);
getline(fin, temp     , ','); losses            = stringToInt   (temp);

作为额外的改进,您可以进一步重构代码以避免如此多的读取操作:

Team::Team(ifstream& fin)
{
    string temp;
    getline(fin, temp);
    const char * ctemp = temp.c_str();
    std::vector<char> buf(ctemp, ctemp + temp.count() + 1);

    char * lasts, * s = buf.data();
    auto next = [&]{
        char * result = strtok_r(s, ",", &lasts);
        assert(result); // …or throw
        s = NULL;
        return result;
    };

    idNumber          = stringToInt   (next());
    idLetter          =                next()[0];
    name              =                next();
    type              =                next();
    rating            = stringToDouble(next());
    ⋮
    programmingSkills = stringToInt   (next());
    ⋮
}

作为最后一步,您甚至可能想要使用方便的提取器类:

class CsvLine {
public:
    CsvLine(const std::string & line) {
        const char * temp = line.c_str();
        buf_.assign(temp, temp + line.length() + 1));
        s_ = buf_.data();
    }

    CsvLine & operator>>(string & x) { x =                next() ; return *this; }
    CsvLine & operator>>(char   & x) { x =               *next() ; return *this; }
    CsvLine & operator>>(int    & x) { x = stringToInt   (next()); return *this; }
    CsvLine & operator>>(bool   & x) { x = stringToBool  (next()); return *this; }
    CsvLine & operator>>(double & x) { x = stringToDouble(next()); return *this; }

private:
    std::vector<char> buf_;
    char * s_, * lasts_;

    char * next() {
        char * result = strtok_r(s_, ",", &lasts_);
        assert(result); // …or throw
        s_ = NULL;
        return result;
    };
};

Team::Team(ifstream& fin)
{
    string line;
    getline(fin, line);
    CsvLine(line)
        >> idNumber >> idLetter >> name >> type >> rating >> notes
        >> canToss >> tossType
        ⋮
        >> driverSkills >> programmingSkills >> ranking >> wins >> ties >> losses;
}
于 2013-06-09T22:22:09.767 回答