Search code examples
cstructfwritefread

Wrong int values using fwrite in C


I'm trying to create a keymanager for a simple UDP client-server application in C. I'm running into problems writing the keys to a text file. I'm currently storing structs into a txt file, but my output was the same when I used ints.

// ...
// if the principal is requesting to registering, store it in a file
if (req.request_type == regista) {
    printf("Writing key to file...\n");
    pFile = fopen("crypt.txt", "ab");
    fwrite(&req, sizeof(struct P2Key), 1, pFile);
    printf("Written: %u %i ", req.principal_id, req.public_key);
    fclose(pFile);
    printf("Done\n");
}

// if pincipal is requesting key
if (req.request_type == request_key) {
    pFile = fopen("crypt.txt", "rb");
    printf("Key requested for: %u %i ", req.principal_id, req.public_key);
    printf("Searching for Requested Key\n");

    while (fread(&res, sizeof(struct P2Key), 1, pFile) == 1) {
        printf("Read: %u %i\n", res.principal_id, res.public_key);
        printf("Line Number: %ld\n", ftell(pFile));

        // if this is the client requested, send the key
        if (req.principal_id == res.principal_id) {
            send_key.principal_id = req.principal_id;
            send_key.public_key = req.public_key;
            printf("Sending Key...\n");
            // ...
        }

Here's the structure being written to the file

typedef struct P2Key {
    enum {
        regista, request_key
    } request_type; /* same size as an unsigned int */
    unsigned int principal_id; /* client or server identifier */
    int public_key; /*  public key */
} P2Key;

The output I'm getting when I attempt to read the file:

 Writing key to file...
 Written: 2 7 Done
 ...
 Writing key to file...
 Written: 1 7 Done
 Key requested for: 2 7 Searching for Requested Key
 Read: 512 1792
 Line Number: 12
 Read: 256 1792
 Line Number: 24
 End of file reached.

I've been at this for hours, any and all help is appreciated.


Solution

  • You are writing in append mode; have you re-created the file since you switched to writing the structs? You don't show or even test the number of bytes written, so you have no idea if the write succeeded or not.

    My first suspect is that you have been appending to this file over time, and it has old data near the beginning that doesn't line up with your structure. I suggest first emptying the file. On UNIX/Linux, you can do this with "> crypt.txt" from the shell.

    Now on to debugging the code. Capture the return value of all reads and writes, they return size_t, so you can at least look at the return value in the debugger. You may want to log an error, etc., if you didn't write the number of bytes you expected to -- the sizeof the struct. Step over the write and close in your debugger, then look at the file with a hex dump or similar utility. Do the values in the file look like what you expect? Does the file contain the same number of bytes as the sizeof your struct?

    Then proceed to the read code. Watch the code load each value from the file with fread. Watch the return value you get from fread -- is it the sizeof your struct? Look at the values in the struct after the read completes. Does it look like it read what you wrote?