Search code examples
cgetoptfclose

fprintf not writing to file, despite fclose()


As the title states I'm trying to write to a file with fprintf, and I've searched on Stack Overflow for why it wouldn't be writing to file. What I've found is that it holds it in memory until you close the file(right?), hence the usage of fclose(). However, it's still not working for me.

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


void printHelp()
{
    printf("Usage: fstring [ char ] [ amount ] Optional:[ outfile ]\n"
           "Example: fstring A 100 out.txt\n");
    exit(1);
}

char *f_string(const char *s, int t)
{
    int i; char *dst = malloc(t * strlen(s) + 1);
    for(i = 0; i < t; i++) {
        strcat(dst, s);
    }
    return dst;
}


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

    while((c = getopt(argc, argv, "f:")) != -1)
        switch(c) {
        case 'f':
            file = optarg;
            break;
        default:
            printHelp();
            return 1;
        }

    if(argc < 3) {
        printf("You need at least two arguments!\n");
        return 1;
    }

    char *res = f_string(argv[1], atoi(argv[2]));
    FILE *f = fopen(file, "w+");
    if(!f) {
        puts(res);
        exit(0);
    } else {
        fprintf(f, "%s", res);
    }

    fclose(f);
    free(res);
    return 0;
}

What I really don't understand is why the above code doesn't work, but this does just fine:

int main(int argc, char *argv[])
{
    char line[80];

    if(argc != 6) {
        fprintf(stderr, "You need to give 5 arguments!\n");
        return 1;
    }

    FILE *in;
    if(!(in = fopen("spooky.csv", "r"))) {
        fprintf(stderr, "File %s doesn't exist!", in);
        return 1;
    }

    FILE *file1 = fopen(argv[2], "w");
    FILE *file2 = fopen(argv[4], "w");
    FILE *file3 = fopen(argv[5], "w");

    while(fscanf(in, "%79s", line) == 1) {
        if(strstr(line, argv[1]))
            fprintf(file1, "%s\n", line);
        else if (strstr(line, argv[3]))
            fprintf(file2, "%s\n", line);
        else
            fprintf(file3, "%s\n", line);
    }

    fclose(file1);
    fclose(file2);
    fclose(file3);
    return 0;
}

The second code works just fine writing to files. Hoping someone can enlighten me. Thanks.


Solution

  • Use optind to find out where non-optional arguments start.

    int main(int argc, char *argv[])
    {
        char c; char *file;
    
        while((c = getopt(argc, argv, "f:")) != -1)
            switch(c) {
            case 'f':
                file = optarg;
                break;
            default:
                printHelp();
                return 1;
            }
    
    
        int index = optind;
        if(argc - index + 1 < 3) {
            printf("You need at least two arguments!\n");
            return 1;
        }
        char *res = f_string(argv[index], atoi(argv[index + 1]));
        FILE *f = fopen(file, "w+");
        if(!f) {
            puts(res);
            exit(0);
        } else {
            fprintf(f, "%s", res);
        }
    
        fclose(f);
        free(res);
        return 0;
    }