acidlategamer
acidlategamer

Reputation: 163

correct way to use fwrite and fread

I wrote a program

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE *fp;
    int r;
    char arr[] = "this is the string";
    char str[20] = {'\0'};

    fp = fopen("fwrite.txt", "w");
    fwrite(arr, 1, sizeof(arr), fp);
    fseek(fp, SEEK_SET, 0);
    r = fread(str, 1, sizeof(arr), fp);

    if(r == sizeof(arr))
        printf("read successfully\n");
    else
    {
        printf("read unsuccessfull\n");
        exit(1);
    }

    printf("read = %d\n", r);
    printf("%s\n", str);

    fclose(fp);
    return 0;
}

I am trying to read in this way but I am not able to do it. What is the problem here, is it that I should put &str[i] and run a loop for fread or will fread be able to put data in the str?

I am getting junk and I don't understand why?

Upvotes: 1

Views: 4172

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 753455

The primary problem is that you have the arguments to fseek() backwards — you need the offset (0) before the whence (SEEK_SET). A secondary problem is that you attempt to read from a file open only for writing. A more minor issue in this context, but one that is generally very important, is that you don't error check the fopen() call. (It is relatively unlikely that this fopen() will fail, but funnier things have been known.) You should also check the fwrite() call (you already check the fread(), of course).

Fixing all these might lead to:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int rc = EXIT_SUCCESS;
    int r;
    const char file[] = "fwrite.txt";
    char arr[] = "this is the string";
    char str[20] = {'\0'};
    FILE *fp = fopen(file, "w+b");
    if (fp == 0)
    {
        fprintf(stderr, "Failed to open file %s for reading and writing\n", file);
        rc = EXIT_FAILURE;
    }
    else
    {
        if (fwrite(arr, 1, sizeof(arr), fp) != sizeof(arr))
        {
            fprintf(stderr, "Failed to write to file %s\n", file);
            rc = EXIT_FAILURE;
        }
        else
        {
            fseek(fp, 0, SEEK_SET);
            r = fread(str, 1, sizeof(arr), fp);
            if (r == sizeof(arr))
            {
                printf("read successful\n");
                printf("read = %d bytes\n", r);
                printf("read data [%s]\n", str);
            }
            else
            {
                printf("read unsuccessful\n");
                rc = EXIT_FAILURE;
            }
        }
        fclose(fp);
    }
    return rc;
}

Example run:

$ ./fi37
read successful
read = 19 bytes
read data [this is the string]
$

Note that this works in part because you write the null byte at the end of the output string to the file, and then read that back in. The file isn't really a text file if it contains null bytes. The b in "w+b" mode isn't really needed on Unix systems where there's no distinction between a binary and a text file. If you're writing null bytes to a file on Windows, you should use the b to indicate binary mode.

If you chose to, you could reduce the 'bushiness' (or depth of nesting) by not having a single return in the main() function. You could use return EXIT_FAILURE; and avoid an else and another set of braces. The code shown is careful to close the file if it was opened. In a general-purpose function, that's important. In main(), it is less critical since the exiting process will flush and close open files anyway.

Upvotes: 4

Phil Fighter
Phil Fighter

Reputation: 96

You can't read in a file with the "w" mode for fopen, use "w+" instead.

"r" - Opens a file for reading. The file must exist.

"w" - Creates an empty file for writing. If a file with the same name already exists, its content is erased and the file is considered as a new empty file.

"a" - Appends to a file. Writing operations, append data at the end of the file. The file is created if it does not exist.

"r+" - Opens a file to update both reading and writing. The file must exist.

"w+" - Creates an empty file for both reading and writing.

"a+" - Opens a file for reading and appending.

Upvotes: 1

Related Questions