Question

I have been dealing with a problem with 3 programs from this book: C How to Program - Deitel They are related to the chapter 11 managing Files (Sequential and random access Files) in my studying method I like to test the example programs before I head the exercises, and I couldn't make work the 3 examples of the random access files (creating, reading and writing) I have got three unexpected behaviors. let me show:

  • First I run the random access file creator, nothing seems weird and I get the finish message. enter image description here

  • Second I compile the writing random access values file, then enter the values, nothing seems weird. Entering values

  • Third I want to use the hare strategy and read the .dat file with notepad to see if the data got saved properly. And surprise some garbage is showed. And i thought well, maybe the double representation doesn't match with the reading program (notepad). So i moved to the fourth step.

Reading File notepad

  • Fourth I compile the reading random access files program. and surprise the data showed isn't what I entered.

    results didn

I didn't want to post this question here cause I know there are more important questions, and more interesting but i can't find what I did wrong, and I have been looking for some time and I finally decided to ask the experts. I leave you the SC below (Thanks!):

/*To create the file*/
#include <stdio.h>

struct clientsData{
    int account;
    char lastname[ 30 ], name[ 30 ];
    double balance;
};

int main(void)
{
    int i; 
    struct clientsData client = { 0, "", "", 0.0 };
    FILE *cfPtr;


    if( ( cfPtr = fopen( "clients.dat", "wb" ) ) == NULL ) {
        printf( "File couldn't be opened. " );
    }
    else{
        printf( "Generating\n" );
        for ( i = 1; i <= 10000; i++ ){
            printf( "-" );
            fwrite( &client, sizeof( struct clientsData ), 1, cfPtr );
        }
            fclose( cfPtr );
    }
    printf( "\nFile succesfully created\n" );
    return 0;
}

/* To write the file */
#include <stdio.h>

struct clientsData{
    int account;
    char lastname[ 30 ], name[ 30 ];
    double balance;
};

int main(void)
{
    FILE *cfPtr;

    struct clientsData client = { 0, "", "", 0.0 };

    if( ( cfPtr = fopen( "clients.dat", "rb+" ) ) == NULL ) {
        printf( "File couldn't be opened. " );
    }
    else{
        printf( "Enter account number"" ( 1 to 10000, 0 to end the input )\n?" );
        scanf( "%d", &client.account );

        while( client.account != 0 ){
            printf( "Enter the lastname, firstname and the balance\n?" );
            fscanf( stdin, "%s%s%lf", client.lastname, client.name, &client.balance );
            fseek( cfPtr, ( client.account - 1 ) * sizeof( struct clientsData ), SEEK_SET );
            fwrite( &client, sizeof( struct clientsData ), 1, cfPtr );
            printf( "Enter account number\n?" );
            scanf( "%d", &client.account );
        }
        fclose( cfPtr );
    }
    return 0;
}

/*To read the File*/
#include <stdio.h>

struct clientsData{
    int account;
    char lastname[ 30 ], name[ 30 ];
    double balance;
};

int main(void)
{
    FILE *cfPtr;

    struct clientsData client = { 0, "", "", 0.0 };

    if( ( cfPtr = fopen( "clients.dat", "rb" ) ) == NULL ) {
        printf( "File couldn't be opened. " );
    }
    else{
        printf( "%-6s%-16s%-11s%10s\n", "Acct", "Lastname", "Firstname", "Balance" );

        while( !feof( cfPtr ) ){
            fread( &client, sizeof( struct clientsData ), 1, cfPtr );

            if( client.account != 0 ){
                printf( "%-6d%-16s%-11s%10.2f\n", &client.account, client.lastname, client.name, &client.balance );
            }
        }
        fclose( cfPtr );
    }
    return 0;
}
Was it helpful?

Solution

Looks like everything is saved correctly. But you print pointers instead of values here:

printf( "%-6d%-16s%-11s%10.2f\n", &client.account, client.lastname, client.name, &client.balance );

Should it be like this?

printf( "%-6d%-16s%-11s%10.2f\n", client.account, client.lastname, client.name, client.balance );

OTHER TIPS

This line in the file reader is wrong:

printf( "%-6d%-16s%-11s%10.2f\n", &client.account, client.lastname, client.name, &client.balance );

As it stands, you're printing addresses (pointers) to the account and balance variables, instead of the values of those variables.

It should read:

printf( "%-6d%-16s%-11s%10.2f\n", client.account, client.lastname, client.name, client.balance );

Useful tip: I found this error by enabling compiler warnings. gcc outputted these warnings:

reader.c:26:28: warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat]
reader.c:26:28: warning: format '%f' expects argument of type 'double', but argument 5 has type 'double *' [-Wformat]

It would be a very good idea to find out how to enable these warnings in your compiler / IDE, as they will save you a lot of time with these kinds of problems.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top