首页 > 解决方案 > 需要帮助弄清楚 fgets 的问题是什么

问题描述

所以基本上我有一个文件指针,指向一个在 0 和 1 之间有 80 位数字的文件,我需要将它们放入一个字符串中,然后对其进行处理。

该函数返回NULL,我找不到问题所在,因为如果它返回NULL它就意味着错误。

    FILE *fpr = fopen(path, "r");
    FILE *fpw = fopen("code.txt", "w");
    char *str = calloc(81, sizeof(char));
    if (fpr == NULL || fpw == NULL) {
        printf("yikes");
    }
    if (fgets(str, 80, fpr) != NULL) { //HERE ITS NULL
        int p1 = 0;
        int p2 = 0;

我真的想透了,我要么真的很笨,要么没有明显的问题。

标签: cnullfgetsfile-pointer

解决方案


代码片段中存在一些问题:

  • 如果任何文件无法打开,您仍然调用,如果是fgets(),它具有未定义的行为。对每个 进行单独测试,打印更明确的错误消息并退出程序。fprNULLFILE*
  • 您应该将数组的大小传递给fgets()81而不是80.
  • 该数组应分配到至少 82 个字节:80 个字符加上尾随换行符和一个空字节终止符。
  • 您不测试内存分配失败。您甚至不应该分配内存,对于像 82 字节这样的小尺寸,本地数组是可以的。

这是一个更正的版本:

#include <errno.h>
#include <stdio.h>

    ...
    char str[82];
    FILE *fpr = fopen(path, "r");
    if (fpr == NULL) {
        fprintf(stderr, "cannot open input file %s: %s\n", path, strerror(errno));
        exit(1);
    }
    FILE *fpw = fopen("code.txt", "w");
    if (fpw == NULL) {
        fprintf(stderr, "cannot open output file %s: %s\n", "code.txt", strerror(errno));
        exit(1);
    }
    if (fgets(str, sizeof str, fpr)) {
        int p1 = 0;
        int p2 = 0;
        ...

始终测试错误条件并打印明确的错误消息,您将保护自己无数小时的调试时间。


推荐阅读