Thread: reading long integer from binary file

  1. #1
    Registered User
    Join Date
    Jul 2009
    Posts
    14

    reading long integer from binary file

    hi all,

    I'm having trouble reading a long integer from a binary file. The long int is 4 bytes long.

    i have, for example:

    Code:
    byte_t bytes_read;
    long temp;
    
    bytes_read = fread(&temp, sizeof(long)*4, 1, filePtr);
    that didn't work so i tried:

    Code:
    byte_t bytes_read;
    long* temp;
    temp = (long*)malloc(sizeof(temp));
    
    bytes_read = fread(temp, sizeof(long)*4, 1, filePtr);
    that still doesn't work

    any ideas? i think it's trivial but i can't wrap my head around it...thanks!
    Last edited by vkoo; 07-13-2009 at 07:28 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Why are you multiplying sizeof(long) by 4? Do you have four longs that you somehow want to read into one number?

  3. #3
    Registered User
    Join Date
    May 2008
    Posts
    87
    Double check how many bytes are are telling fread() to read in.

  4. #4
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    1) read what tabstop wrote.
    2) bytes_read is a misnomer here -- fread returns 'the number of items successfully read' -- the third argument. Here, it will return 1 on success. Read thy man pages.
    3) Finally, if this is a binary file you're reading, are you aware of endianness? Using your code, the endianness of the file and the host machine must match. There are better ways to write I/O code that will read a binary integer from a file, regardless of host machine endianness.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Cactus_Hugger View Post
    There are better ways to write I/O code that will read a binary integer from a file, regardless of host machine endianness.
    The important factor isn't the endianness of the machine, but the endianness of the quantity within the file. That needs to be specified before anything else can take place. There are three possibilities: big endian, little endian, and native. If the specification is for "native," then it is perfectly acceptable (and more efficient) to read the value directly, as is happening here.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Registered User
    Join Date
    Jul 2009
    Posts
    14
    Quote Originally Posted by tabstop View Post
    Why are you multiplying sizeof(long) by 4? Do you have four longs that you somehow want to read into one number?
    the sizeof(long)*4 is just telling fread() to read 4 bytes at a time. so: fread(test, sizeof(long)*4 , 1, file) means it will read 1 block of 4 bytes once...unless i'm confused with this part. Regardless, fread(test, sizeof(long), 4, file) which reads a long type 4 times doesn't work as well...

    Quote Originally Posted by jason_m View Post
    Double check how many bytes are are telling fread() to read in.
    i've specified fread to read 4 bytes at one time

    Quote Originally Posted by Cactus_Hugger View Post
    1) read what tabstop wrote.
    2) bytes_read is a misnomer here -- fread returns 'the number of items successfully read' -- the third argument. Here, it will return 1 on success. Read thy man pages.
    3) Finally, if this is a binary file you're reading, are you aware of endianness? Using your code, the endianness of the file and the host machine must match. There are better ways to write I/O code that will read a binary integer from a file, regardless of host machine endianness.
    i know bytes_read returns the number of bytes read..i was referring to the memory address of test...sorry for the confusion!

    In the file format...the number is only 4 bytes long and that's what i've specified fread to do, read once 4 bytes (of type long) at a time...unless i'm completely misunderstanding what i just wrote...

    thanks for all your help!!
    Last edited by vkoo; 07-13-2009 at 09:04 PM.

  7. #7
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    the sizeof(long)*4 is just telling fread() to read 4 bytes at a time
    No. A long probably is 4 bytes on your system, so sizeof(long) is probably 4. Thus you're asking for 1 item of 16 bytes, which is what tabstop was originally trying to point out to you.

    i know bytes_read returns the number of bytes read
    I don't think you understand me -- fread() does not return the number of bytes read. It returns (as the manual says) the number of items read. If an 'item' is a 'byte' then in that case only will it return the number of bytes read. That case is not yours, given how you're calling fread(). You are saying (currently) "read 1 sizeof(long)*4 bytes long item" -- it will return 1 on success, 0 on failure in this case for the arguments you are passing it. (but you should probably be reading just sizeof(long), if you just want 1 integer.)

    The important factor isn't the endianness of the machine, but the endianness of the quantity within the file.
    I apparently wasn't clear, but yes -- that is my point. The OP must know the endianness of his file. I would rule native out -- it's fairly rare. If the OP is writing the file himself as 'native', it is only because he is unaware of endianness in the first place.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  8. #8
    Registered User
    Join Date
    Jul 2009
    Posts
    14
    Quote Originally Posted by Cactus_Hugger View Post
    No. A long probably is 4 bytes on your system, so sizeof(long) is probably 4. Thus you're asking for 1 item of 16 bytes, which is what tabstop was originally trying to point out to you.

    I don't think you understand me -- fread() does not return the number of bytes read. It returns (as the manual says) the number of items read. If an 'item' is a 'byte' then in that case only will it return the number of bytes read. That case is not yours, given how you're calling fread(). You are saying (currently) "read 1 sizeof(long)*4 bytes long item" -- it will return 1 on success, 0 on failure in this case for the arguments you are passing it. (but you should probably be reading just sizeof(long), if you just want 1 integer.)

    I apparently wasn't clear, but yes -- that is my point. The OP must know the endianness of his file. I would rule native out -- it's fairly rare. If the OP is writing the file himself as 'native', it is only because he is unaware of endianness in the first place.
    so i want:

    Code:
    long* temp;
    temp = (long*)malloc(sizeof(long));
    
    fread(temp, sizeof(temp), 1, file);
    to read in a 4 byte long integer then? i'm trying that right now...it's still wrong so i don't know if my code is right then..

    thanks for your patience!

  9. #9
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    No one said sizeof(long *) == sizeof(long).

    A few suggestions:
    * Error checking
    * Don't cast malloc()
    * Free when you're done.

    In fact, I wouldn't be using malloc() for 4 bytes :\

    My suggestion: Stop guessing.
    Last edited by zacs7; 07-13-2009 at 10:24 PM.

  10. #10
    Registered User
    Join Date
    Jul 2009
    Posts
    14
    i just thought that previously if i'm reading in a long type...i read in a long type and save it to the address of a long variable

    i'm just clueless why this doesn't work..it's not like it has a null character at the end.

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by vkoo View Post
    i just thought that previously if i'm reading in a long type...i read in a long type and save it to the address of a long variable

    i'm just clueless why this doesn't work..it's not like it has a null character at the end.
    Yes, but sizeof(temp) is not necessarily going to be the size of a long -- sizeof(long) is going to be the size of a long, and temp is not a long variable -- it's a pointer. (Now granted on many machines in current use these are the same size, but they don't have to be.) The typical idiom is to use sizeof(*temp) -- the size of the thing temp points to -- in your malloc and your read.

  12. #12
    Registered User
    Join Date
    Jul 2009
    Posts
    14
    Quote Originally Posted by tabstop View Post
    Yes, but sizeof(temp) is not necessarily going to be the size of a long -- sizeof(long) is going to be the size of a long, and temp is not a long variable -- it's a pointer. (Now granted on many machines in current use these are the same size, but they don't have to be.) The typical idiom is to use sizeof(*temp) -- the size of the thing temp points to -- in your malloc and your read.
    oh ic...that's right...that makes a lot more sense but it still doesn't work...i'm still having problems:

    Code:
    int main(int argc, char* argv[])
    {
    	if(!InitCUDA()) {
    		return 0;
    	}
    
    	char* fileID;
    	long tempIntReader;
    	size_t bytes_read;
    
    	/* File Input Variables */
    	int lenFileName;
    	char *fileName;
    	FILE *whichFile;
    	char* buf;
    
    	buf = (char*)malloc(sizeof(char)*17);
    	//tempIntReader = (long*)malloc(sizeof(long));
    
    	/* # pixels and # bytes in a frame*/
    	int frm_size;
    
    	INT16_T *h_idata;	/* input data on host */
    	float *h_odata;		/* image data on host */
    
        //frm_size = 512 x FFT_LENGTH;	/* #pixels = image width x image length */
    
    	printf("Please enter the full file name (i.e. imagefile.raw)\n-> ");
    	scanf("%c", &fileName);
    		
    	if((whichFile = fopen("1.RAW", "r"))== NULL) {
    		printf("Error while loading data from file %s.\n", fileName);
    		exit(0);
    	} else {
    		bytes_read = fread(buf, sizeof(buf), 17, whichFile);
    		
    		for(int i = 0; i < 17; i++){
    			printf("%c", buf[i]); 
    		}
    		
    		memset(buf, '\0', sizeof(buf));
    
            printf("\n");
            bytes_read = fread(&tempIntReader, sizeof(long), 1, whichFile);
            printf("%d", tempIntReader);
    i tried that first, just reading in a long int and saving it to tempIntReader

    then i tried:

    Code:
    long* tempIntReader;
    tempIntReader = (long*)malloc(sizeof(long));
    fread(tempIntReader, sizeof(long), 1, whichFile);
    then i tried:

    Code:
    long* tempIntReader;
    tempIntReader = (long*)malloc(sizeof(long));
    fread(tempIntReader, sizeof(*tempIntReader), 1, whichFile);
    i continously get this error:
    Unhandled exception at 0x00403508 in CUDAWinApp4.exe: 0xC0000005: Access violation reading location 0xffffff31.

    i'm more confused now than ever because I'm reading the right about of bytes, I now have the right size to save what was read in and I have the right type. What am I missing?

    I tried resetting the iterator for the filePtr by:
    fseek(whichFile, 17, SEEK_SET);

    which sets the iterator at the exact spot of my long int
    Last edited by vkoo; 07-14-2009 at 10:28 AM.

  13. #13
    pwning noobs Zlatko's Avatar
    Join Date
    Jun 2009
    Location
    The Great White North
    Posts
    132
    I think there is a poblem with:
    bytes_read = fread(buf, sizeof(buf), 17, whichFile);

    sizeof(buf) is the sizeof a pointer (probably 4), so the above line is trying to read 4*17 bytes. The parameter should be sizeof(char) or better yet, sizeof(*buf).
    The line is over running the buf memory and causing memory corruption.

  14. #14
    Registered User
    Join Date
    Jul 2009
    Posts
    14
    Quote Originally Posted by Zlatko View Post
    I think there is a poblem with:
    bytes_read = fread(buf, sizeof(buf), 17, whichFile);

    sizeof(buf) is the sizeof a pointer (probably 4), so the above line is trying to read 4*17 bytes. The parameter should be sizeof(char) or better yet, sizeof(*buf).
    The line is over running the buf memory and causing memory corruption.
    true true...thanks i've fixed that...but my long integer is just reading the wrong numbers and throwing random numbers back at me...

  15. #15
    pwning noobs Zlatko's Avatar
    Join Date
    Jun 2009
    Location
    The Great White North
    Posts
    132
    Quote Originally Posted by vkoo View Post
    true true...thanks i've fixed that...
    Ok, assuming you fixed it, perhaps your file does not look like what you think it does. If the file is small enough, perhaps you could post it, along with the latest version of your main function, and the number you're expecting to find at location 17. If you're using the emacs editor, put your data file into hexl-mode (the command is esc-x hexl-mode) to examine it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A development process
    By Noir in forum C Programming
    Replies: 37
    Last Post: 07-10-2011, 10:39 PM
  2. Looking for constructive criticism
    By wd_kendrick in forum C Programming
    Replies: 16
    Last Post: 05-28-2008, 09:42 AM
  3. Replies: 8
    Last Post: 03-26-2007, 05:48 PM
  4. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM