1

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 . . .
user3405291
  • 5,371
  • 3
  • 32
  • 81

2 Answers2

3

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;
Community
  • 1
  • 1
Blastfurnace
  • 17,441
  • 40
  • 50
  • 66
2

In your do{} while() loop, you are incrementing i each time. Consider the case of a zero-length file. The first pass of the loop will occur, after which i will be equal to 1. Since EOF will be reached immediately, no later pass will occur. However, no samples were actually found in that case.

You will want to decrement i once after the end of the loop. Remember the difference here between counting how many samples you found (one less than the number of times your loop runs) and the number of elements in the array you attempted to populate.

Elros
  • 263
  • 2
  • 9
  • I'm going to decrement i once after the while loop. That will solve the problem. However I'm not quite clear on how eof() works, I should study about it. – user3405291 Jul 22 '14 at 15:37