3

I'm very new to C, and I am having trouble with fwrite.

I'm looking to use a struct that holds two values:

struct keyEncode{
    unsigned short key[2];
    unsigned short encoded[2];
};

I then declare my struct and a pointer to that struct in my main:

struct keyEncode keynEncode;
struct keyEncode *storedVal = &keynEncode;

I then assign values to the struct and want to write the struct to a file using fwrite:

keynEncode.key[0] = k1[0];
keynEncode.key[1] = k1[1];
keynEncode.encoded[0] = p[0];
keynEncode.encoded[1] = p[1];
// i tried to use storedVal.key[0] = k1[0]; but i was getting compile errors

fwrite(storedVal, sizeof(storedVal), 0xffff, fp);

Now my problem is that fwrite writes nothing to the file.

Where am I going wrong?

molleman
  • 2,934
  • 16
  • 61
  • 92
  • 2
    Removed C++ tag as this is C code. – Billy ONeal Nov 11 '10 at 15:08
  • What's the 0xffff? You're writing 65k of records? No, here should be 1. – Vovanium Nov 11 '10 at 15:11
  • What you're doing is conceivably okay, but in general, the compiler is allowed to insert padding in between the members of the struct there. Therefore, just writing out the binary representation of the `struct` out to disk isn't going to yield consistent results between compilers and/or compiler versions and/or compiler settings. – Billy ONeal Nov 11 '10 at 15:11

5 Answers5

15

You are using sizeof on a pointer, this won't calculate the size of the effective struct but the one of the pointer (that could be 4 or 8 bytes). Try with sizeof(struct keyEncode) (sizeof(keyEncode) is enough if you are using C++).

Then I don't get why you have 0xFFFF as count, shouldn't it be just 1?

Jack
  • 131,802
  • 30
  • 241
  • 343
  • ok thank you very much, i dont really understand the third parameter in the fwrite, if you could give some insight that would be great??? – molleman Nov 11 '10 at 15:12
  • also i would like to write the value of the struct to a binary file – molleman Nov 11 '10 at 15:13
  • 1
    the third parameter is used in combination with size if you want to write multiple items with just a fwrite. Basically the total number of bytes written should be `(second parameter * third parameter)`. With second you define the size of every item while third decides how many of them you are gonna write, like if you need to write out an array. – Jack Nov 11 '10 at 15:14
  • The second param is the size of each of the items you are writing. The third is the number of those you are writing. It returns the number actually written, so you should check the return value to ensure everything happened as expected – The Archetypal Paul Nov 11 '10 at 15:15
  • Yes, what you are gonna write with fwrite is binary if the fields of the struct are binary, ASCII if they are `char *`. Of course they'll be mixed together. – Jack Nov 11 '10 at 15:15
4

Assuming you only have one such struct, then you need to change:

fwrite(storedVal, sizeof(storedVal), 0xffff, fp);

to

fwrite(storedVal, sizeof(*storedVal), 1, fp);

Paul R
  • 208,748
  • 37
  • 389
  • 560
1

The arguments to fwrite() are the data to be printed, the size of one data item, the number of data items, and the file pointer.

You have two problems with the sizes:

  1. You specify 'sizeof(storedVal)', which is the size of a pointer - not the size of the structure.
  2. You specify that 65,535 of them need to be written.

So, you need to use:

 if (fwrite(storedVal, sizeof(*storedVal), 1, fp) != 1)
    ...error handling...

Note that fwrite() returns the number of items written. In the general case, you have n items to write, and you should check:

 if (fwrite(storedVal, sizeof(*storedVal), n, fp) != n)
    ...error handling...
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0
FILE *fp = fopen("c:\\test", "wb");
if (fp != NULL) {
    fwrite(storedVal, sizeof(keynEncode), 1, fp);
    fclose(fp);
}
Snaipe
  • 1,191
  • 13
  • 25
Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
0
 // i tried to use storedVal.key[0] = k1[0]; but i was getting compile errors

For this one. storedVal is a pointer to the struct. C's pointer dereference operator is -> so you want

 storedVal->key[0] = k[0];
The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134