fprintf 不写入文件,尽管 fclose()

fprintf not writing to file, despite fclose()

如标题所述,我正在尝试使用 fprintf 写入文件,并且我在 Stack Overflow 上搜索了为什么它不会写入文件。我发现它一直保存在内存中,直到您关闭文件(对吗?),因此使用了 fclose()。但是,它仍然不适合我。

#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;
}

我真的不明白为什么上面的代码不起作用,但这很好:

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;
}

第二个代码可以很好地写入文件。希望有人能赐教。谢谢

根本原因是参数乱了。

调用 getopt 后,指向参数 argv 的指针已被操纵,不再指向原始参数。因此,之后当您使用 argv[1]argv[2] 作为 fstring 函数时,它们不是您传递给主函数的参数。

最简单的更正是在将 argv 传递给 getopt 之前将参数存储在临时变量中。

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

    char *v1 = argv[1];
    int v2 = atoi(argv[2]);


    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(v1, v2);
    FILE *f = fopen(file, "w+");
    if(!f) {
        puts(res);
        exit(0);
    } else {
        fprintf(f, "%s", res);
    }

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

来自 getopt() 的手册页:默认情况下,getopt() 在扫描时置换 argv 的内容,因此最终所有非选项都在末尾 .

如果您使用选项 Abc 10 -f out.txt 调用您的可执行文件,那么在 getopt 处理之后 argv[1] 将是 -f 并且 argv[2] 将是 out.txt .所以你必须换行

char *res = f_string(argv[1], atoi(argv[2]));

char *res = f_string(argv[3], atoi(argv[4]));

否则,help 的用法是完全错误的,因为根据代码,没有什么是可选的。

函数 f_string() 必须更正:

char *f_string(const char *s, int t)
{
    int i; 
    char *dst = malloc(t * strlen(s) + 1);
    dst[0] = '[=12=]';  // <-----

    for(i = 0; i < t; i++) {
        strcat(dst, s);
    }
    return dst;
}

如果没有正确的初始化 strcat() 可能会在 dst 的中间开始。

使用optind找出非可选参数的起始位置。

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;
}