2

I'm writing a program that is creating a lookup table from two tables that are in two separate files. When I read the first table, everything is read correctly. However, when I am reading the second file, fopen doesn't seem to open the whole file.

I say this because the compiler implements the _iobuf file structure and _cnt seems to be initialized a whole lot lower (_cnt = 530) than when initialized the first time(_cnt ~ 4096) and as I read from the file it decreases.

Here is a snippet of my code:

int vertical,horizontal,channels,count;
FILE *fp;

fp = fopen(filename,"r");
if(fp==NULL){
    cout << "File not found" << endl;
    return Mat();
}else{
    cout << "Opening and Reading " << filename << endl;
}

//Read header
fread(&count,4,1,fp);
cout << "ReadHistogram(): Count number is " << count;
if(count!= 5){
    cout << "Header file reads: " << count << endl;
    return Mat();
} 

//Read size
fread(&vertical,4,1,fp);
//cout << "ReadHistogram(): Vertical size:" << vertical <<endl;

fread(&horizontal,4,1,fp);
//cout << "ReadHistogram(): Horizontal size:" << horizontal <<endl;

fread(&channels,4,1,fp);
//cout << "ReadHistogram(): Channel size:" << channels<<endl;

//Create Mat array
int size[] = {vertical, horizontal, channels};
Mat histogram(3,size,CV_64F,Scalar::all(0));

//Read in array
count = 0;
for(int i=0;i<vertical;i++){
    for(int j=0;j<horizontal;j++){
        for(int k=0;k<channels;k++){
            double temp5;
            fread(&temp5,8,1,fp);
            histogram.at<double>(i,j,k) = temp5;
            if(count <= 300){
                cout << "Array(" << i+1 << "," << j+1 << "," << k+1 << ")" << "=" << histogram.at<double>(i,j,k) << endl;
                cout << "Temp5 is " << temp5 << endl;
            }
            count++;
        }
    }
}
cout << "Done reading " << filename << endl;
fclose(fp);
return histogram;

PS: I have been trying to look up what exactly is _cnt in the FILE structure and I can't find anything of the sort. I would appreciate any pointers anyone can give.

netcoder
  • 66,435
  • 19
  • 125
  • 142
Rommel Alonzo
  • 61
  • 2
  • 8
  • Are you able to read the entire contents of the file? – mah Sep 04 '12 at 20:19
  • Yea, I can read values but only the at the beginning of the for loop are the values correct. The problem is it's that after a certain point, fread begins to return the same value which isn't what is in the file contains. – Rommel Alonzo Sep 04 '12 at 20:34
  • 1
    What happens if you read the second file first? What has changed between the two times? Is there any threading involved? Are you using the file anywhere else at the same time? Try making your functions a lot shorter. Please post a [SSCCE](http://sscce.org/). – Karl Bielefeldt Sep 04 '12 at 21:03
  • 1
    The members of the `FILE` structure are intended to be private. Don't worry about whether they have the values you expect. If defined operations on the file (`fopen`, `fread`, `fclose`, etc.) don't behave correctly, *then* you have a legitimate problem. – Keith Thompson Sep 04 '12 at 21:56

3 Answers3

2

It looks like you're reading a binary file in text mode. Try adding "b" to the flags in the fopen:

fp = fopen(filename, "rb");

Also check the return value of fread and if it's fewer bytes than you expected, check the ferror code.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
0

Your code looks fine, although you should check the return values of fread. If you're looking into the internals of FILE, you're only asking for confusion. _cnt probably has to do with how much of the file is buffered in memory. It is not part of the API, and is thus not documented and you should not look at it.

What is the problem, exactly? When does fread fail and what does it return?

Keith Randall
  • 22,985
  • 2
  • 35
  • 54
  • When I begin reading the file, all the values that fread is returning are correct. However, after a certain point, fread begins to return the same value over and over again. The only reason that I mention _cnt is because fread begins reading the same value over and over when _cnt = 0. – Rommel Alonzo Sep 04 '12 at 20:32
  • the fread that is causing me problems is the one that is in the nested for loop. – Rommel Alonzo Sep 04 '12 at 20:34
  • I'm sorry. I said all the values that fread is returning are correct. This is only true for the first couple of values. But after a certain point, it starts returning the same values over and over again. – Rommel Alonzo Sep 04 '12 at 20:38
  • 1
    @RommelAlonzo: I mean the return value of `fread` - not the value returned in `temp5`, but the integer returned by `fread` which tells you how many elements it read. When it returns 0, use `ferror` or `feof` to find out what happened. – Keith Randall Sep 04 '12 at 21:27
  • Bearing with what others have said, do yourself a favor just for sanity. allocate a buffer the size of the entire file, then read the whole thing in one shot. Debug it, and see if the contents, byte for byte, are correct *then*. Something tells me we're missing something.. Oh,and check the return results from `fread` =) – WhozCraig Sep 04 '12 at 21:28
  • @KeithRandall:I'm sorry. I completely forgot fread returns something. It starts returning 1 at the beginning of the reads but as soon as the problem starts it returns 0. – Rommel Alonzo Sep 04 '12 at 21:56
  • @RommelAlonzo: (repeating myself) So what do `feof` and `ferror` return after that happens? – Keith Randall Sep 04 '12 at 22:03
  • @KeitRandall:Well it does run into an EOF. Thats what perror prints out when the file pointer reaches eof – Rommel Alonzo Sep 04 '12 at 22:14
  • @RommelAlonzo: I bet there is nothing wrong with `fopen`/`fread`/etc. There is something wrong with your input file and/or your understanding of what it contains. – Keith Randall Sep 04 '12 at 22:15
0

Yea, I can read values and they are correct. The problem is it's that after a certain point, fread begins to return the same value.

I'm going to go out on a limb here with an answer rather than continued discussion; I'll delete if I'm off-base.

I expect what is happening is you have read the entire contents of your file however you have not stopped reading; subsequent calls to fread() are returning an error (which you aren't checking for) and not modifying the contents of your read buffer.

Either check the return of fread(), or call feof() to check your status, or both.

mah
  • 39,056
  • 9
  • 76
  • 93
  • I agree, but the thing is its that the actual file contains more values than what the program is reading. I have two files that are the exact same size that I am reading. When I read the entire first file, everything is read correctly. The problem comes when I read the second file. Both files are the same size. – Rommel Alonzo Sep 04 '12 at 20:41
  • Same size, in this case, does not matter since your program believes the size is based on the contents; if those contents are wrong (and suggest there is more data than there really is, based on `vertical`, `horizontal`, and `channels`) then your program will keep calling fread(). – mah Sep 04 '12 at 20:43
  • Well, I'm using the same files in a matlab program but matlab is reading all the values correctly. – Rommel Alonzo Sep 04 '12 at 20:50