在c ++中读取文件时fstream无限循环

时间:2012-03-10 03:22:57

标签: c++ infinite-loop

我在学校使用C ++参加CS101课程。我有一个程序必须以这种格式读取文件:

Ramirez, Manny
1572838992 a 4 b 5 x 4 a 7 c 3 c 4 *
Kemp, Matt
3337474858 a 4 b 4 b 4 a 4 *

应该读取文件,计算每个学生的GPA并输出学生的姓名,ID,单位和GPA。我已经尝试了一段时间不同的事情,而且我一直在无限循环中来回走动。我得到了一位朋友的帮助,他让我加入了一些东西。

我已经尝试在while(!eof)循环中更改循环的条件这么多次我无法统计它们。每当我查看在线做什么时,我得到的建议就是不要使用while!eof,因为它有导致无限循环的倾向。好吧,我现在知道了,但我的教授希望我们这样做。

这是我的代码:

 #include <iostream>
    #include <fstream>
    #include <string>
    #include <iomanip>
    #include <sstream>
    using namespace std;
    int main() {

    char grade;
    int units=0, studentsGrade=0, studentUnits=0;
    int unitTotal=0;
    float gradeTotal=0, gpa = 0;
    string inputName, outputName, fullName;
    long ID;
    ifstream inputFile;
    ofstream outputFile;

    cout << "Please enter the input filename: ";
    cin >> inputName;
    cout << "Please enter the output filename: ";
    cin >> outputName;
    inputFile.open(inputName.c_str());
    if (inputFile.fail()) 
        cout << "Bad input file name." << endl;
    else {
    outputFile.open(outputName.c_str());
    outputFile << left << setw(25) << "Name" << setw(15) << "ID" << setw(15)
    << "Units" << setw(15) << "GPA" << endl;
    outputFile << "--------------------------------------------------------------------------------" << endl;
    cout << left << setw(25) << "Name" << setw(15) << "ID" << setw(15)
    << "Units" << setw(15) << "GPA" << endl;
    cout << "--------------------------------------------------------------------------------" << endl;





    getline(inputFile, fullName);
    while (!inputFile.eof()) {
        gpa = 0;
        unitTotal = 0;
        gradeTotal = 0;
        inputFile >> ID;
        outputFile << setw(25) << fullName;
        outputFile << setw(15) << ID;
        cout << setw(25) << fullName << setw(15) << ID;
        string line;
        getline(inputFile,line);
        istringstream iss(line);
        while (!iss.eof()) {
            units = 0;
            iss >> grade >> units;
            if (grade == '*')
                break;
            if (units > 0 && units <=5 && (grade == 'a' || grade == 'A')) {
                gradeTotal += 4 * units;
                studentsGrade += 4 * units;
                unitTotal += units; 
                studentUnits += units;}
            else if (units > 0 && units <=5 && (grade == 'b' || grade == 'B')) {
                gradeTotal += 3 * units;
                studentsGrade += 3 * units;
                unitTotal += units;
                studentUnits += units; }
            else if (units > 0 && units <=5 && (grade == 'c' || grade == 'C')) {
                gradeTotal += 2 * units;
                studentsGrade += 2 * units;
                unitTotal += units;
                studentUnits += units; }
            else if (units > 0 && units <=5 && (grade == 'd' || grade == 'D')) {
                gradeTotal += 1 * units;
                studentsGrade += 1 * units;
                unitTotal += units;
                studentUnits += units; }
            else if (units > 0 && units <=5 && (grade == 'f' || grade == 'F')) {
                unitTotal += units;
                studentUnits += units; }
            else if (grade == '*') {
                unitTotal += 0;}
            else {
                unitTotal += 0; }
        } 
        gpa = (float)gradeTotal / unitTotal;
        outputFile << fixed << showpoint;
        outputFile << setw(15) << unitTotal << setw(15) << setprecision(2) << gpa << endl;
        cout << fixed << showpoint;
        cout << setw(15) << unitTotal << setw(15) << setprecision(2) << gpa << endl;
        getline(inputFile,fullName);
        }
    outputFile << "The GPA for all students is " << setprecision(2) << (float)studentsGrade / studentUnits;
    cout << "The GPA for all students is " << setprecision(2) << (float)studentsGrade / studentUnits << endl;

}
    inputFile.close();
    outputFile.close();
    cout << endl;
    return 0;
    }

如果有人能向我解释为什么我会继续无限循环,我会非常感激。

2 个答案:

答案 0 :(得分:4)

虽然需要通过运行代码进行验证,但您似乎设置了failbitbadbit,但未设置eof。例如,在您执行其他读取而不是getline()之后,可能会发生这种情况,例如inputFile >> ID;

由于您只检查eof,因此循环无休止地运行,I / O错误将被忽略。我要说尝试使用getline()的结果并使用operator void*的{​​{1}}而不是检查std::istream

如果您的教授希望您仅使用eof(),请尝试解决错误检查问题。解决方案可能是使用特殊值并假设如果读取操作没有将值设置为其他值,则它已经失败,并且突破循环。例如,在阅读之前将eof()设置为ID,并确保之后不是LONG_MAX

毕竟 - 只需在一个小型工作数据集上运行调试器下的代码,然后逐步查看会发生什么。熟悉调试器并练习故障排除技巧。这肯定会为你在整个职业生涯中节省很多时间。

另见 - http://www.cplusplus.com/reference/iostream/ifstream/

祝你好运!

答案 1 :(得分:1)

检查eof是不够的。您还需要至少在关键点检查读取函数的结果,例如在读取值之后。例如,因为文件末尾可能有空格。您可以为此测试if (cout.fail())

如果你能从这里找到一种编写零件的方法会更好:

if (units > 0 && units <=5 && (grade == 'a' || grade == 'A')) {

作为一个像这样的身体的循环:

        gradeTotal += i * units;
        studentsGrade += i * units;
        unitTotal += units; 
        studentUnits += units;