Home > database >  How do I read properly from a binary file?
How do I read properly from a binary file?

Time:12-28

first, I'm really sorry for posting such a long code, but I already cut it and I think that is everything I need for my problem. Your also welcome to give me feedback what I could improve for my future questions :)

Also there could be gramma/translation mistakes, because english isn't my first language.

My problem: I want the user to be able to read this structure:

typedef struct {
    char movieTitle[30];
    unsigned int yearPublished;
    char director[50];
    char genre[50];
    float profit;
} movie_t;

from a binary file that has already 4 movies in it, but should also be able to store max 100 movie structures like defined here:

//global var.
// ================================================================
#define MAX_STORAGE 100
movie_t movieData[MAX_STORAGE];
movie_t movieRecord;
unsigned int movieCount = 0;

With my code that I already wrote below, I can't somehow read all movies out of the file, because my "count checker" tells me everytime that just one movie was read. Also just one movie is showing in my console output code below my "readFile" function.

// main functions --- read from file
// ================================================================
int
readFile(const char* fileName)
{
    //open file
    FILE* read = fopen(fileName, "rb");
    if (!read)
    {
        printf("ERROR: Could not open the file!\n");
        return -1;
    }
    else
    {
        printf("%s were opened successfully.\n\n", fileName);
    }

    //read from file
    int count = 0;
    while (!feof(read))
    {
        size_t count = fread(&movieRecord, sizeof(movieRecord), 1, read);
        if (count == 0)
        {
            printf("ERROR: Read process was unsuccessful or incomplete!\n");
        }
        if (count == 1)
        {
            printf("Successfully read %i movie.\n", count);
        }
        else
        {
            printf("Successfully read %i movies.\n", count);
        }
        return count;
    }
    fclose(read);

    return 0;
}

This is the console output where ALL movies from the file should be showing up. Also they should be showing with a number (Num.) from 1 - 100.

// main functions --- console Output
// ================================================================
void
consoleOutput(movie_t movieData2, unsigned index)
{
    printf("MOVIE DATA         Num. %u\n\n", index);

    printf("Movie title     : %s\n", movieData2.movieTitle);
    printf("Publishing year : %u\n", movieData2.yearPublished);
    printf("Director        : %s\n", movieData2.director);
    printf("Genre           : %s\n", movieData2.genre);
    printf("Profit          : %.2f\n", movieData2.profit);
}

This is how my main function looks like if you would like to see it:

// MAIN
// ================================================================
int main(void)
{
    // defaultname for file
    char fileName[50] = "movies.dat";

    // variable for loop
    int stopLoop = 0;

    // loop
    do {
        // Output menu
        printf("\nMENU:\n");
        printf("(a)   Show all movies\n");
        printf("(o)   Read moviefile\n");
        printf("(q)   Exit programm\n");
        printf("\nYour choice: ");

        // User input
        char ch = _getch();
        printf("%c\n\n", ch);

        // Switch case for user input
        switch (ch)
        {
        case 'q': // Exit programm
            stopLoop = 1;
            break;
        case 'a': // Show all movies
            consoleOutput(movieRecord, movieCount = readFile(fileName));
            break;
        case 'o': // Read moviefile
            readFile(fileName);
            break;
        default:
            printf("==> Invalid input!\n");
        }

    } while (!stopLoop);

    return 0;
}

Sidenote: because the user is able to input new movies, they should be able to save that data to the same file from where they read it. But that's something I want to test myself first, before I ask around for help.

I would really appreciate any help, because I'm still a beginner in coding and this problem is frustrating me a little....

Thank you very much in advance! :)

CodePudding user response:

You are returning from your loop body after reading only one entry. If you really wish to read all the entries in the file, you'll need to change your reading loop to reading into your array, which you can in fact get rid of all together thanks to how fread works:

// main functions --- read from file
// ================================================================
int
readFile(const char* fileName)
{
    //open file
    FILE* read = fopen(fileName, "rb");
    if (!read)
    {
        printf("ERROR: Could not open the file!\n");
        return 0; // note that since you'll probably assign the output to movieCount, it might be better to return 0 on failure
    }
    else
    {
        printf("%s were opened successfully.\n\n", fileName);
    }

    // Here's where the problem, you only ever read out one movie entry into movieRecord and returned
    // You can use fread to read out the entire file into the array instead
    // It would also be better not to use a global variable for this, instead taking in a pointer to an movie_t array to readFile instead but I left it using the global as per the original program
    size_t count = fread(movieData, sizeof(movie_t), MAX_STORAGE, read);
    if (ferror(read))
    {
        printf("ERROR: Read process was unsuccessful or incomplete!\n");
        fclose(read);
        return 0;
    }
    if (count == 1)
    {
        printf("Successfully read %i movie.\n", count);
    }
    else
    {
        printf("Successfully read %i movies.\n", count);
    }
    fclose(read);

    return count;
}

From here, you'll have movieData populated with the data from your file and should adjust the rest of your program accordingly.

  • Related