从文件读取后输出中有额外的零行

时间:2015-05-03 21:17:37

标签: c++ file fileoutputstream

我是一名尝试学习C ++的初学者。我试图从文件中读取以下信息:

Dean DeFino 88 98 99
莎莉约翰逊78 89 82
比尔班尼75 79 81
Thomas Billows 78 84 89

然而,我得到以下输出,我无法弄清楚原因:

Dean DeFino 88 98 99
         0 0 0
莎莉约翰逊78 89 82
         0 0 0

以下是代码:

#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;

const int NAMESIZE = 15;
const int MAXRECORDS = 50;
struct Grades                             // declares a structure
{
    char name[NAMESIZE + 1];
    int test1;
    int test2;
    int final;

};

typedef Grades gradeType[MAXRECORDS];    
 // This makes gradeType a data type
 // that holds MAXRECORDS
 // Grades structures.

void readIt(ifstream&, gradeType, const int);

int main()

{    
     ifstream indata;
     indata.open("graderoll.dat");
     int numRecord = 4;                
     gradeType studentRecord; 

     if(!indata)
     {
        cout << "Error opening file. \n";
        cout << "It may not exist where indicated" << endl;
        return 1;
     }

    readIt(indata, studentRecord, MAXRECORDS); 

    // output the information 
        for (int count = 0; count < numRecord; count++)
    {
           cout << studentRecord[count].name << setw(10) 
            << studentRecord[count].test1
            << setw(10) << studentRecord[count].test2;
           cout << setw(10) << studentRecord[count].final << endl;
    }                

    return 0;
}

void readIt(ifstream& inData, gradeType gradeRec, const int max)

{
   int total = 0;

   inData.get(gradeRec[total].name, NAMESIZE);
   while (inData)
   {
     inData >> gradeRec[total].test1;
     inData >> gradeRec[total].test2;
     inData >> gradeRec[total].final;

     total++;    

     inData.clear(); 
     inData.get(gradeRec[total].name, NAMESIZE);


  }

}

有任何建议可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

我解决了问题:

void readIt(ifstream& inData, gradeType gradeRec, const int max)

{
   int total = 0;

   inData.get(gradeRec[total].name, NAMESIZE);
   while (inData)
   {
     inData >> gradeRec[total].test1;
     inData >> gradeRec[total].test2;
     inData >> gradeRec[total].final;

     total++;    

     inData.ignore(NAMESIZE, '\n');
     inData.get(gradeRec[total].name, NAMESIZE);


  }

}

inData.ignore(NAMESIZE,&#39; \ n&#39;); 将使字符数组正常工作。这是因为字符数组限制为15个字符。因此,如果指定忽略接下来的15个字符,或者直到遇到换行转义序列,则会正确读取文件的每一行。

答案 1 :(得分:0)

问题在于您使用:

while (inData)

将iostream转换为布尔值时,布尔值反映了EOF标志的状态。但是,在尝试从文件末尾读取数据后, 之后才会设置EOF标志。

所以会发生什么情况是您的代码成功读取文件的最后一行,然后循环并且尚未设置EOF标志,并尝试从文件中读取一个 more 行。这不会读取任何实际数据而你会得到零。之后,EOF标志被设置,你的循环终止。

修复此问题的一种方法可能是在读取预期数据后测试EOF标志,所以:

   while (true)
   {
     inData >> gradeRec[total].test1;
     inData >> gradeRec[total].test2;
     inData >> gradeRec[total].final;

     if (!inData) {
       break;
     }

     total++;    

     inData.clear(); 
     inData.get(gradeRec[total].name, NAMESIZE);
   }

你也可以重新安排你的循环,这样你就不会有代码来读取名字两次,一次是在循环之外,一次是在结束时。