【问题标题】:Extra lines of zeros in output after reading from a file从文件读取后输出中的额外零行
【发布时间】:2015-07-13 05:06:30
【问题描述】:

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

Dean DeFino 88 98 99
萨莉·约翰逊 78 89 82
比尔·本尼 75 79 81
托马斯·比洛斯 78 84 89

但是,我得到以下输出,但我不知道为什么:

迪恩·德菲诺 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);


  }

}

有什么建议可以帮助我解决这个问题吗?

【问题讨论】:

  • 对不起,这对我没有帮助。我不相信我的问题与eof 相关
  • 文件是在linux还是windows上创建的?你运行的是linux还是windows?
  • @benjy-kessler 该文件是在 Windows 中创建的
  • @benjy-kessler,我使用的是 Mac OS 终端,但我已经在 Windows 中尝试过,得到了同样的结果

标签: c++ file fileoutputstream


【解决方案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, '\n'); 将使字符数组正常工作。这是因为字符数组被限制为 15 个字符。因此,如果指定忽略接下来的 15 个字符或直到遇到换行符转义序列,则文件的每一行都会被正确读取。

【讨论】:

    【解决方案2】:

    问题在于你的使用:

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

    您还可以稍微重新排列循环,这样您就没有代码来读取名称两次,一次在循环外,一次在结尾。

    【讨论】:

    • 不幸的是,当我将 while 循环中的条件设置为 true 时,它​​只读取文件的第一行并为其余三个指定实例设置零,这与我之前的情况不同。似乎 while 循环正在读入数组,文件中的区域之间有一行零。有没有办法告诉程序消耗行尾?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    相关资源
    最近更新 更多