Why does (while .. getchar()) does not write to my file, in C?

Viewed 85

I need to write a program that asks the user to enter strings, each string ends when the user presses 'Enter'.

  • The program needs to receive the file name as a parameter, the file should be opened and closed for each operation and for every string entered, the program should append the string to the end of the file (on a new line).

This is my code so far:

 int is_file_exists(char *file_name)
{
    
    FILE *file;
    if ((file = fopen(file_name,"r"))!=NULL)    
        {
            /* file exists */
            fclose(file);
            return 1;
        }    
    else  
        {
            //File not found, no memory leak since 'file' == NULL
            //fclose(file) would cause an error
            return 0;
        }
        
}

int main(int argc, char **argv)
{
    char c;
    FILE *file;

    if (argc >= 2)
    {
         if (is_file_exists(argv[1]))
         {
             file = fopen(argv[1], "w");
         }
         else
         {
             return 0;
         }
    }
    else
    {
         file = fopen("file.txt", "w");
    }

    while ((c = getchar()) != EOF)
    {
        putc(c, file);
    }

    return 0;
}

So far the code compiles and file is being created, but nothing is being written inside of it.

Edit: I also need some function pointers, see my comments on selected answer

2 Answers

I think one of the problem was that you were opening and closing a file, and then reopening it subsequently. It is better to just leave it open using a pointer while simultaneously testing that there were no issue to open the file. Another problem was that you were writing in the file, don't you prefer to append text to it? Well it's your decision. As for the code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h> // exit

typedef struct mystruct {
    char *exit_word;
    void (*exit_fptr)(int); // man exit
    int (*strcmp_fptr)(const char *, const char*); // man strcmp
}              t_mystruct;

int is_file_exists(char *filename, FILE **file)
{
    return (*file = fopen(filename,"a")) > 0;
}

#define BUFF_SIZE 1024

int main(int argc, char **argv)
{
    char c;
    FILE *file;
    t_mystruct s = {.exit_word = "-exit", .exit_fptr = &exit, .strcmp_fptr = &strcmp};

    if (argc >= 2) {
         if (!(is_file_exists(argv[1], &file)))
            return 0;
    }
    else
         file = fopen("file.txt", "a"); // open the file in append mode

    char buffer[BUFF_SIZE];
    while (42) {
        int i = 0;
        memset(buffer, 0, BUFF_SIZE);
        while ((c = getchar()) != '\n')
            buffer[i++] = c;
        if (!s.strcmp_fptr(buffer,s.exit_word)) {// exit if user type exit, allow you to fclose the file
            fclose(file);
            s.exit_fptr(EXIT_SUCCESS); // better to use the define
        }
        buffer[i] = '\n';
        fputs(buffer, file);
    }
    fclose(file);
    return 0;
}

your code can work

remember to press Ctrl+d when finished input. the file will have the content your expected

your code wait for EOF to quit the loop. Ctrl+d is a way to input EOF, or else the program never ends. putc will write to cache at first, then write to disk. this an optimization mechanism of File System. you can choose to avoid this by DirectIO when open file.

when program terminate normally, file will be closed automatically, then data in cache will be copy to disk;

but when program terminated abnormally, data in cache might be lost.

file should be closed

fclose is needed. open and close should be organized in pair just as malloc and free.

Related