我是一名尝试学习C ++的初学者。我试图从文件中读取以下信息:
然而,我得到以下输出,我无法弄清楚原因:
以下是代码:
#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);
}
}
有任何建议可以帮我解决这个问题吗?
答案 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);
}
你也可以重新安排你的循环,这样你就不会有代码来读取名字两次,一次是在循环之外,一次是在结束时。