Search code examples
cfgetsfputs

w+ not working when trying to read file content


Code:

#include <stdio.h>

void main() {
    FILE *ptr;
    char buff[255];
    ptr = fopen("Test.txt", "w+");

    if (ptr != NULL) {
        printf("Success\n");
    }

    fputs("Hello", ptr);

    fgets(buff, 255, (FILE *)ptr);
    printf("%s", buff);
    fclose(ptr);
}

The file "Text.txt" has the content "Hello" when I opened it, but I just can't print it out with fgets. What did I do wrong here?


Solution

  • There are multiple problems in your code:

    • You must issue a call to fseek(), fsetpos() or rewind() to switch between writing to and reading from the stream, and vice versa.

    • The prototype for main without arguments is int main(void).

    • There is no need to cast ptr in fgets(buff, 255, (FILE *)ptr);. Useless casts can hide type mismatches and other similar bugs.

    • You do not test the return value of fgets() before passing buff to printf(). This has undefined behavior if fgets() fails, a it does in your case.

    • You do test the return value of fopen(), but still pass a potentially null ptr to other stream functions, invoking undefined behavior.

    Here is a corrected version:

    #include <stdio.h>
    
    int main(void) {
        FILE *ptr;
        char buff[255];
    
        ptr = fopen("Test.txt", "w+");
        if (ptr == NULL) {
            printf("Cannot open Test.txt\n");
            return 1;
        }
        printf("Success\n");
    
        fputs("Hello", ptr);
        rewind(ptr);
        if (fgets(buff, sizeof buff, ptr)) {
            printf("%s", buff);
        } else {
            printf("Cannot read from stream\n");
        }
        fclose(ptr);
        return 0;
    }