6
\$\begingroup\$

The program reads a file containing a list of numbers, and then writes the ones divisible by 3 to another file, and prints the remaining ones (non-divisible) to a third file.

Declaring, opening, and closing the files is alone over 50% of the code, is there anyway to make it more compact?

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

int main(void){
    FILE *in_file; /*input file*/
    FILE *out_file_divis; /*FIle that contains numbers divisible by 3*/
    FILE *out_file_remain; /*File that contains the rest of the numbers*/

    if((in_file = fopen("total", "r")) == NULL){
        perror("total");
        exit(EXIT_FAILURE);
    }

    if((out_file_divis = fopen("divis", "w")) == NULL){
        perror("divis");
        exit(EXIT_FAILURE);
    }

    if((out_file_remain = fopen("remain", "w")) == NULL){
        perror("remain");
        exit(EXIT_FAILURE);
    }

    int number;

    while(fscanf(in_file, "%i", &number) == 1){
        if(number%3 == 0){
            fprintf(out_file_divis, "%i\n", number);
        }

        else{
            fprintf(out_file_remain, "%i\n", number);
        }
    }

    fclose(in_file);
    fclose(out_file_divis);
    fclose(out_file_remain);

    return 0;
}
\$\endgroup\$
  • \$\begingroup\$ Ones are never divisible by 3 ;) \$\endgroup\$ – Thijs Riezebeek Mar 2 '17 at 9:06
  • 1
    \$\begingroup\$ @ThijsRiezebeek I'm not sure what you mean? Ones are added to the remain, not the divis file. I don't see the issue. \$\endgroup\$ – user127566 Mar 2 '17 at 13:56
  • \$\begingroup\$ Never mind, it was a joke. Your title states that you print 'ones' divisible by 3, as in the number 1. But 1s are never divisible be 3. Forget I said anything. \$\endgroup\$ – Thijs Riezebeek Mar 2 '17 at 14:14
5
\$\begingroup\$

The easiest way to make this more compact is to write a function to handle opening a file and just pass in the name and mode you want. Something like this:

FILE* open_file_or_exit(const char* filename, const char* mode)
{
    FILE* fileHandle = NULL;
    if((fileHandle = fopen(filename, mode)) == NULL){
        perror(filename);
        exit(EXIT_FAILURE);
    }
    return fileHandle;
}

Your main() then becomes:

int main(void){
    FILE *in_file = open_file_or_exit("total", "r");
    FILE *out_file_divis = open_file_or_exit("divis", "w');
    FILE *out_file_remain = open_file_or_exit("remain", "w");
    // ... rest of main ...
}

Any time you find yourself repeating the same few lines of code, that's a good sign that it should go into a function.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy