-1

I am working in Ubuntu on OpenCV. I am trying to read a text file which contains numbers, but I keep getting garbage values and the same value repeats every time the function loops. Here is that part of the code:

FILE* fid = fopen("/trial","r");
while (fgetc(fid) != EOF)
{
    fscanf(fid, "%f", &trainsample);
    cout << trainsample << endl;
    cvSetReal2D(traindata, i, j, trainsample);
    j = j + 1;
    if (j == 6)
        i = i + 1;
}
Kevin
  • 53,822
  • 15
  • 101
  • 132
SB26
  • 225
  • 1
  • 6
  • 17

5 Answers5

4

Why don't you use C++ ifstream for this task?

#include <iostream>
#include <fstream>

int main(){
    std::ifstream fileStream("/trail");
    double trainsample;
    if(!fileStream.good()){
        std::cerr << "Could not open file." << std::endl;
        return 1;
    }
    while(fileStream >> trainsample){           
        std::cout << trainsample << std::endl;
    }
    if(fileStream.fail())
        std::cerr << "Input file stream error bit is set, possible read error on file." << std::endl;               
}

If you prefer C file handling try

#include <cstdio>

int main(){
    FILE *fid = fopen("/trail","r");
    double trainsample;
    if(fid){
        while(!feof(fid)){
            fscanf(fid,"%lf",&trainsample); // Please notice "lf" when using double. Using "f" will result garbage.
            printf("%lf\n",trainsample);
        }
    }
}

See also cstdio and ifstream.

Zeta
  • 103,620
  • 13
  • 194
  • 236
  • 1
    `while(fileStream.good())` is not the way to go. It'll usually iterate one too many times. The proper way is to put the extraction statement in the condition. – jrok Jan 09 '12 at 22:44
  • @jrok: Ah, I see. Didn't notice that `std::istream::operator>>` returns `(*this)`. Thanks! – Zeta Jan 09 '12 at 22:54
  • It works but reads the file line by line. If my file has one number in each line then ifstream will read these numbers one by one. Is there a way to read all the numbers at once? – Ruchir Aug 14 '15 at 08:21
2

fgetc() reads a character from a file. It is equivalent to getc. You can use !feof(fid) as your condition instead. The garbage values are because you are not at the correct position while reading the float values from the file and as a result, other characters/special characters are influencing the values being read in by C.

Neo
  • 1,554
  • 2
  • 15
  • 28
  • Giving this some further thought, how are the values separated in your text file? You might need to read in an additional character/string if they are space-tab-or-comma separated! – Neo Jan 09 '12 at 21:54
  • 1
    He likely should **not** use `!feof(fid)` as the loop condition since it won't be set until after he attempts to read... – Evan Teran Jan 09 '12 at 21:55
  • hmm.. I didn't know that @EvanTeran. I ran similar loops successfully before. – Neo Jan 09 '12 at 21:59
  • I think I understand what you mean. What's gonna happen if my file is empty? Please tell me if this is correct: If the file is not empty and contains at least one value, the feof() will return false, and control will enter the loop. Subsequent reads/operations on the file will ensure that EOF is marked at the right time. But if my file is empty, then will feof() fail on the first try? Is that what you were trying to point out? – Neo Jan 09 '12 at 22:05
  • Its seperated by space.And all the values in the file are numbers,some floats some integers – SB26 Jan 09 '12 at 22:05
  • @SB26 .. in that case, you will want to use an fgetc() after fscanf(). But then, make sure you check for boundary conditions! Eg: How to ensure that the last value is properly read in without any errors if there is no space after the last value? You can always again if you are not able to find a solution. :) – Neo Jan 09 '12 at 22:10
  • @Neo: it's not just if the file is empty (though that is a concern too!), the pattern: `while(!feof(f)) { /* read data */ }` will essentially always attempt an extra read. How bad that is depends on how you use the result of the read operation. But it's easier in general to just write the loop correctly... – Evan Teran Jan 09 '12 at 22:32
  • @Neo: see the accepted answer to http://stackoverflow.com/questions/5431941/in-c-is-while-feof-always-wrong for more details – Evan Teran Jan 09 '12 at 22:39
2

Is there any particular reason you're using C-style I/O routines instead of C++ stream operators?

#include <iostream>
#include <stdexcept>
#include <fstream>
...
std::ifstream fid("/train");
if (!fid.good())
    // could not open file, panic here
else
{
  float trainsample;
  while (fid >> trainsample)
  {
    std::cout << trainsample << std::endl;
    ...
  }
  if (fid.eof())
    std::cout << "Hit end of file" << std::endl;
  else if (fid.fail())
    std::cout << "Read error on file" << std::endl;
}
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

ASSUMPTION:

  • The /trail file contains only one float value per line

Having said the above, you don't need the while loop with fgetc(), instead you need the following

while (fscanf(fid,"%f",&trainsample) == 1) {
    cout<<trainsample<<endl;
    /* you can put all you logic here */

}
Sangeeth Saravanaraj
  • 16,027
  • 21
  • 69
  • 98
  • @SB26 Can you do a `cat trail` and show us what is stored in that file?! That will give us some hint on how to read them. OTOH, is your `fopen()` successfully returns a valid `FILE` descriptor?! – Sangeeth Saravanaraj Jan 09 '12 at 22:12
0

My guess is that fopen is failing, and so fscanf is failing (not reading anything) and the garbage value you're getting is in fact the uninitialized contents of the trainsample variable, which of course never changes.

Kyle Jones
  • 5,492
  • 1
  • 21
  • 30