我有一个压缩的文本文件,有7行非常长的文本,其中包含JPEG编码文件的解码信息。
当我试图用我的C程序逐行读取解压文件时,我得到了正确的前3行和后3行,只是第4行没有像预期的那样作为字符串读取。
第四行的输出是一个很长的字符串,其中包含fscanf1
如果我用记事本或十六进制编辑器查看输入文件,一切看起来都很好。
如果我手动创建一个结构相同(但行较短)的文本文件,0可以正常工作。
如果我用我的程序解压文件,或者手动解压,没有区别。

FILE *tmpdata;
char enc_path[256];
int arrsize;
// Building the absolute Path
sprintf(enc_path, "%s%stmp.txt", dest, src_name);

arrsize = unzip(); // gives back size of the file

// not the best way to create the output strings,
// but I don't know the size of the lines.

char masse[10];
char ytabelle[arrsize / 3];
char cbtabelle[arrsize / 3];
char crtabelle[arrsize / 2];
char ywerte[arrsize  /3];
char cbwerte[arrsize / 3];
char crwerte[arrsize / 3];

if ((tmpdata = fopen(enc_path, "r")) == NULL) {
    printf("Error: can´t read input file\n");
    return EXIT_FAILURE;
}

fscanf(tmpdata, "%s %s %s  %s %s %s %s", masse, ytabelle, cbtabelle, crtabelle, ywerte, cbwerte, crwerte);

输入文件如下所示:
512x512个
Y{42:110000;13:111000;…;0:0;}
CB{42:110000;13:111000;…;0:0;}
铬{42:110000;13:111000;…;0:0;}
0001110101011100111000111100011。。。
10001101110111000010100011100110。。。
1000111011011111011001011011011011011011。。。
如果我打印单独的字符串:
512x512个
Y{42:110000;13:111000;…;0:0;}
CB{42:110000;13:111000;…;0:0;}
111001111111000110001111111000。。。
0001110101011100111000111100011。。。
10001101110111000010100011100110。。。
1000111011011111011001011011011011011011。。。

最佳答案

程序不能正常运行的原因有很多:
使用自动存储(即堆栈上的存储)可能会分配过多的数据,从而导致不稳定的行为。
文件中的字符串可能包含嵌入的空格,导致fscanf()读取单词而不是行。
您不会告诉fscanf()目标数组的大小。fscanf()可能会将数据存储在目标数组的末尾之外,溢出到下一个数组(这将解释观察到的行为)或导致其他一些未定义的行为。
当目标数组不是简单的常量时,传递它们的大小是非常麻烦的。我建议您使用fgets()而不是fscanf()来读取文件内容,并将malloc()的数组分配到更大的大小,以避免出现问题:

    FILE *tmpdata;
    char enc_path[256];
    size_t arrsize;

    // Building the absolute path
    snprintf(enc_path, sizeof enc_path, "%s%stmp.txt", dest, src_name);

    arrsize = unzip(); // gives back size of the file

    // not the best way to create the output strings,
    // but I don't know the size of the lines.

    char masse[16];
    size_t ytabelle_size = arrsize + 2;
    size_t cbtabelle_size = arrsize + 2;
    size_t crtabelle_size = arrsize + 2;
    char *ytabelle = malloc(ytabelle_size);
    char *cbtabelle = malloc(cbtabelle_size);
    char *crtabelle = malloc(crtabelle_size);
    size_t ywerte_size = arrsize + 2;
    size_t cbwerte_size = arrsize + 2;
    size_t crwerte_size = arrsize + 2;
    char *ywerte = malloc(ywerte_size);
    char *cbwerte = malloc(cbwerte_size);
    char *crwerte = malloc(crwerte_size);

    if (!ytabelle ||!cbtabelle ||!crtabelle ||!ywerte ||!cbwerte ||!crwerte) {
        printf("Error: cannot allocate memory\n");
        return EXIT_FAILURE;
    }

    if ((tmpdata = fopen(enc_path, "r")) == NULL) {
        printf("Error: cannot open input file\n");
        return EXIT_FAILURE;
    }

    if (!fgets(masse, sizeof masse, tmpdata)
    ||  !fgets(ytabelle, ytabelle_size, tmpdata)
    ||  !fgets(cbtabelle, cbtabelle_size, tmpdata)
    ||  !fgets(crtabelle, crtabelle_size, tmpdata)
    ||  !fgets(ywerte, ywerte_size, tmpdata)
    ||  !fgets(cbwerte, cbwerte_size, tmpdata)
    ||  !fgets(crwerte, crwerte_size, tmpdata)) {
        printf("Error: cannot read input file\n");
        return EXIT_FAILURE;
    }
    // file contents were read, arrays should have a trailing newline, which
    // you should strip or handle in the decoding phase.
    ...

如果您使用的是GNUlibc或一些现代Posix系统,那么可以使用m中的fscanf()前缀为从文件中读取的单词分配空间。使用此功能可以实现更简单但不可移植的解决方案:
    FILE *tmpdata;
    char enc_path[256];
    size_t arrsize;

    // Building the absolute path
    snprintf(enc_path, sizeof enc_path, "%s%stmp.txt", dest, src_name);

    arrsize = unzip(); // gives back size of the file

    // not the best way to create the output strings,
    // but I don't know the size of the lines.

    char masse[16];
    char *ytabelle = NULL;
    char *cbtabelle = NULL;
    char *crtabelle = NULL;
    char *ywerte = NULL;
    char *cbwerte = NULL;
    char *crwerte = NULL;

    if ((tmpdata = fopen(enc_path, "r")) == NULL) {
        printf("Error: cannot open input file\n");
        return EXIT_FAILURE;
    }

    if (fscanf(tmpdata, "%ms %ms %ms %ms %ms %ms %ms", &masse,
               &ytabelle, &cbtabelle, &crtabelle,
               &ywerte, &cbwerte, &crwerte) != 7) {
        printf("Error: cannot read input file\n");
        return EXIT_FAILURE;
    }
    ...

附言:与德语不同,英语中名词的首字母不大写,但语言、人名和地名等例外情况除外。

10-08 09:05