skip to Main Content

Take a look at this code that allows a user to write data to a txt file.

#include <stdio.h>

int main(void)
{
   FILE *cfPtr = NULL;

   if ( (cfPtr = fopen("clients.txt","w")) == NULL ){
        puts("File could not be opened");
   }else{
        puts("Enter the account, name, and balance");
        puts("Enter EOF to end input.");
        printf("%s", "? ");
        int account = 0;
        char name[30] = "";
        double balance = 0.0;
        scanf("%d%29s%lf",&account,name,&balance);
        
        while (!feof(stdin)){
            fprintf(cfPtr,"%d %s %.2fn",account,name,balance);
            printf("%s", "? ");
            scanf("%d%29s%lf",&account,name,&balance);
        }

        fclose(cfPtr);
   }
}

You can test it with

Enter the account, name, and balance
Enter EOF to end input.
? 100 Jones 24.98
? 200 Doe 345.67
? 300 White 0.00
? 400 Stone -42.16
? 500 Rich 224.62

If I terminate the program with Ctrl+d, the program works fine and the above data is successfully written to the file. However, if I terminate it with Ctrl+c, nothing written in the txt file. I’m wondering what is happening here. Why the program not at least writes the correct data immediately?

The compiler is gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0.

2

Answers


  1. Pressing CTRL-D in a terminal doesn’t terminate the program. It sends an EOF to the program (i.e. it closes the standard input stream) which the feof function can detect.

    Pressing CTRL-C however sends the SIGINT signal to the program. This signal, if not explicitly caught, will cause the program to terminate immediately.

    Login or Signup to reply.
  2. In addition to dbush’s very correct explanation, note that the behavior of this program can be modified so that output (or at least most of it) does get written to the file by explicitly flushing the output with fflush on each loop iteration. Doing this the program will output to the output file immediately. As it stands, if you’re not seeing any output in that file, it almost certainly means your system is trying to be efficient and not flushing the stream until it either sees sufficient data or it gets closed. Neither happens due to the Ctrl-C.

    I’d also suggest the else is unnecessary.

    #include <stdio.h>
    
    int main(void) {
        FILE *cfPtr = NULL;
    
        if ((cfPtr = fopen("clients.txt","w")) == NULL) {
            puts("File could not be opened");
            return 1;
        }
    
        puts("Enter the account, name, and balance");
        puts("Enter EOF to end input.");
        printf("%s", "? ");
        int account = 0;
        char name[30] = "";
        double balance = 0.0;
        scanf("%d%29s%lf", &account, name, &balance);
            
        while (!feof(stdin)) {
            fprintf(cfPtr,"%d %s %.2fn", account, name, balance);
            fflush(cfPtr);
            printf("%s", "? ");
            scanf("%d%29s%lf", &account, name, &balance);
        }
    
        fclose(cfPtr);
    }
    

    Further note: ensure you check the return value from scanf calls as a means of validating input. There’s more to validation than that but it’s a start.

    You can likely also structure your loop so that you don’t have to repeat yourself.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search