c++do-whileeofoff-by-one

Off by one error in while loop with eof()


I have an off-by-one error in the following piece of C++ code and I can not figure it out. Can anybody please help. I have the code and its output below. Best.

double* alloc_Array=new double[m_int_NumChann*m_int_NumSamples];
int int_SizeArray=int(0);
std::ifstream File;
File.open(m_char_Address);
if(File.is_open()){
    std::cout<<"input file opened...\n";
    int i=int(0);
    do{
        File>>alloc_Array[i];
        i++;
    }while(!File.eof());
    int_SizeArray=i;
}else{
    std::cerr<<"ERROR: input file can't be opened.\n";
    system("pause");
}
File.close();
if((m_int_NumChann*m_int_NumSamples)!=int_SizeArray){
    std::cerr<<"WARNING: number of samples multiplied by number of channels is not equal to total data points in the input file:\n";
    std::cerr<<"       number of samples in each channel = "<<m_int_NumSamples<<'\n';
    std::cerr<<"       number of channels = "<<m_int_NumChann<<'\n';
    std::cerr<<"       total data points by multiplication = "<<m_int_NumSamples*m_int_NumChann<<'\n';
    std::cerr<<"       number of data points in the input file = "<<int_SizeArray<<'\n';
    system("pause");
}

Output:

   input file opened...

   WARNING: number of samples multiplied by number of channels is not equal to tota
   l data points in the input file:

   number of samples in each channel = 77824

   number of channels = 11

   total data points by multiplication = 856064

   number of data points in the input file = 856065

   Press any key to continue . . .

Solution

  • The simplest way to fix this is to not loop on eof().

    There are well-known issues with trying to loop on eof() or good() correctly, read these questions for examples: Why is iostream::eof inside a loop condition considered wrong? and Testing stream.good() or !stream.eof() reads last line twice

    You can reorder your code so it will only increment i when a value has been successfully read:

    int i=int(0);
    while (File >> alloc_Array[i]) {
        i++;
    }
    int_SizeArray=i;