Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

~ !dentity

macrumors newbie
Original poster
May 1, 2009
5
0
Ok, I'm writing a tool that opens a file, reads data, and then prints it, my problem is, I can't figure out how to use the function headerData() correctly, and someone at some point told me also I'm comparing a string when I should be assigning it to an int, or something like that.
I'm very new at this, and just started a couple days ago.

With this code, I want it to print interpreted data read from a file:

File Loaded
Head String: Ehed

However I'm getting an error on line 14:
* if (headString = "Ehed") {*
Assignment makes integer from pointer without a cast.

I'm afraid I don't understand,
Could someone give me an example of the correct way to do this, and explain what I am doing wrong, and what I should be doing instead?
Thanks!

Code:
#include <stdio.h>
#include <stdint.h>

int main( int argc, char *argv[] )
{
	FILE *fp;

	uint32_t headString = headerData( headString );
	
	if (fp = fopen( "PathToFile", "r+")) 
	{
		printf("File Loaded");
		headerData( headString );
		if (headString = "Ehed") {
			printf("Head String: %c%c%c%c\n", headString >> 24 & 0xFF, headString >> 16 & 0xFF, headString >> 8 & 0xFF, headString & 0xFF);
		}
		
	}
return 0;
}

uint32_t read_little_32(const unsigned char *p)
{
	return p[0] | p[1] << 8 | p[2] >> 16 | p[3] >> 24;
}


int headerData( uint32_t argc, char *argv[], FILE *fp )
{
	unsigned char uHeadString;
	uint32_t headString;
	
	fseek(fp, 0x2C0, SEEK_SET);
	fread(&uHeadString, 1, 5, fp);
	headString = read_little_32(&uHeadString);
	
	return headString;
}

/*
 In the file:
 Assume 0x0 till 0x2C0 is just 00's.
 2C0 - 2C4 in the file is 0x64656845 (ASCII - dehE)
 assume from 2C5 - EOF = 00's.
 */
 
I'm no C guru but you might need to use == instead of =. In most languages (but not all) = will try to assign your "Ehed" to the headString variable.

Just a guess till somebody smart comes along.
 
I'm no C guru but you might need to use == instead of =. In most languages (but not all) = will try to assign your "Ehed" to the headString variable.

Just a guess till somebody smart comes along.

Thanks, I'll try it.

[edit]

Tried it, now I'm getting a different warning: comparison between a pointer and an integer

[/edit]
 
SilentPanda is correct, but I also see a couple other problems.

Your calls to headerData() within main() doesn't seem to be correct. You're supposed to pass in argc, argv, and a pointer to a FILE. Instead you're passing some uint32_t (which isn't even declared yet in the first call).

It looks like you might have parameters and return values mixed up a bit. I would recommend consulting a C book or tutorial to see how functions are called.

Also comparing the uint32_t and the "Ehed" C-string is almost certainly not what you want to do. It looks like headerData packs 4 bytes in the uint32_t, so you either need to convert the int to a C-string and compare strcmp, or pack the string into another int yourself and compare with ==.

Also, you should probably forward declare headerData() so it is visible to main().

I haven't gotten too specific on purpose to help you explore and learn on your own, but certainly come back if you have trouble. Be sure to explain exactly what you've tried, why you thought it would work, and what errors you saw.
 
Thanks, Yeah I'm trying to learn from an old Microsoft book written in 1988. :p
My mistake was jumping around the chapters trying to learn what I wanted to do. So yeah, now I'm a bit mixed up.

Thanks for the help, I'll try to get this working using your suggestions.

Thanks!

Edit, could you give me an example of forward declaring my headerData() function?
 
What are you trying to learn? What is your ultimate goal? This code is custom-written to a strange file, and doesn't really do anything. It's scary, overflows, and does unnatural things with characters to store them in an int, and so on.

With that said, here's a "working" version that performs the task as I understood it:
Code:
#include <stdio.h>
#include <stdint.h>

uint32_t read_little_32(const unsigned char*);
uint32_t headerData(FILE *);

int main( int argc, char *argv[] ) {
        FILE *fp;
        uint32_t headString;
        uint32_t expectedValue = 0x64656845;

        if (fp = fopen( "PathToFile", "r+")) {
                headString = headerData(fp);
                printf("File Loaded\n");
                printf("Head: %x, expected: %x\n",headString,expectedValue);
                if (headString == expectedValue) {
                        printf("Head String: %c%c%c%c\n", headString >> 24 & 0xFF, headString >> 16 & 0xFF, headString >> 8 & 0xFF, headString & 0xFF);
                }

        }
        return 0;
}

uint32_t read_little_32(const unsigned char *p) {
        return p[3] | p[2] << 8 | p[1] << 16 | p[0] << 24;
}


uint32_t headerData(FILE *fp) {
        unsigned char uHeadString[5];

        fseek(fp, 0x2C0, SEEK_SET);
        fread(&uHeadString, 1, 5, fp);
        return read_little_32(uHeadString);

}

/*
 In the file:
 Assume 0x0 till 0x2C0 is just 00's.
 2C0 - 2C4 in the file is 0x64656845 (ASCII - dehE)
 assume from 2C5 - EOF = 00's.
 */

Note that by posting this i do not endorse doing things like this, ever.

The things that were changed:
Forward declarations of the two functions
A change in the signature of headerData. There was no reason for it to get argc and argv, and if read_little_32 (which doesn't actually read anything...) returns a uint32_t, so should headerData.
Change how and where headString is called. The file must be open and the FILE * must be passed in.
Compare headString to the integer value of the 4 characters desired, not a const char *. "xyz" gives you the address of a character array, which should not be compared to anything using == in the vast majority of cases.
Changed headString to have enough space to store 5 characters that are being read from the file.
Changed headString to return the result of read_little_32 directly, no need for a temporary variable.
Changed the bit shifts in read_little_32 so the characters are in the order they were read in memory. The previous implementation was going to get 0 for the things shifted to the right, etc.
Moved braces onto the line with the statement that starts them. This is just personal preference.

I created a file at PathToFile in the working directory, and this seems to "work" now.

Again, though, it would be best to share with us what your goal is, as this program, if it teaches you anything, will be leading you down the wrong path.

-Lee
 
What are you trying to learn? What is your ultimate goal? This code is custom-written to a strange file, and doesn't really do anything. It's scary, overflows, and does unnatural things with characters to store them in an int, and so on.

With that said, here's a "working" version that performs the task as I understood it:
-Lee

Thanks,

My ultimate goal, is just to learn C, however:
As a hobby, I modify files to a certain game, to create mod's as I call them.
My goal for this application, is simply to open the file I specify, go throughout the file, read and print back data to my screen, so that I don't have to go through and look for the data myself everytime, as it can be quite time consuming.

Basic file layout in this case:
Head string
file info
file data
Foot string
 
I know you're trying to learn C, but honestly for something like this it would me much easier with a more modern language with much more advanced string and file handling libraries. Python, Ruby, Objective-C/Cocoa, etc.
 
I know you're trying to learn C, but honestly for something like this it would me much easier with a more modern language with much more advanced string and file handling libraries. Python, Ruby, Objective-C/Cocoa, etc.

Yep, I know, but I just wanted to get a background in C before I moved on to something else. I plan on moving to ruby obj-c next.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.