【问题标题】:fgets() not reading from a text file?fgets() 没有从文本文件中读取?
【发布时间】:2013-11-24 07:31:56
【问题描述】:

我有一个函数 loadsets()(load settings 的缩写),它应该从名为 Progsets.txt 的文本文件中加载设置。 loadsets() 成功时返回 0,检测到致命错误时返回 -1。但是,实际上Progsets.txt 读取的部分代码(三个 fgets())似乎都失败并返回空指针,因此除了一堆空值之外根本不加载任何东西。我的代码有问题吗?当我运行代码时,fp 是一个有效的指针,我能够打开它进行阅读。那怎么了?

此代码用于使用 cmd 加载我非常基本的文本编辑器程序的默认文本颜色。

标题:

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

#define ARR_SIZE 100

struct FINSETS
{
    char color[ARR_SIZE + 1];
    char title[ARR_SIZE + 1];
    char maxchars[ARR_SIZE + 1];
} SETTINGS;

loadsets():

int loadsets(int* pMAXCHARS) // load settings from a text file
{
    FILE *fp = fopen("C:\\Typify\\Settings (do not modify)\\Progsets.txt", "r");
    char *color = (char*) malloc(sizeof(char*) * ARR_SIZE);
    char *title = (char*) malloc(sizeof(char*) * ARR_SIZE);
    char *maxchars = (char*) malloc(sizeof(char*) * ARR_SIZE);
    char com1[ARR_SIZE + 1] = "color ";
    char com2[ARR_SIZE + 1] = "title ";
    int i = 0;
    int j = 0;
    int k = 0;
    int found = 0;

    while (k < ARR_SIZE + 1) // fill strings with '\0'
    {
        color[k] = title[k] = maxchars[k] = '\0';
        SETTINGS.color[k] = SETTINGS.maxchars[k] = SETTINGS.title[k] = '\0';
        k++;
    }

    if (!fp) // check for reading errors
    {
        fprintf(stderr, "Error: Unable to load settings. Make sure that Progsets.txt exists and has not been modified.\a\n\n");
        return -1; // fatal error
    }

    if (!size(fp)) // see if Progsets.txt is not a zero-byte file (it shouldn't be)
    {
        fprintf(stderr, "Error: Progsets.txt has been modified. Please copy the contents of Defsets.txt to Progsets.txt to manually reset to default settings.\a\n\n");

        free(color);
        free(title);
        free(maxchars);

        return -1; // fatal error
    }

    // PROBLEMATIC CODE:

    fgets(color, ARR_SIZE, fp);      // RETURNS NULL (INSTEAD OF READING FROM THE FILE)
    fgets(title, ARR_SIZE, fp);      // RETURNS NULL (INSTEAD OF READING FROM THE FILE)
    fgets(maxchars, ARR_SIZE, fp);   // RETURNS NULL (INSTEAD OF READING FROM THE FILE)

    // END OF PROBLEMATIC CODE:

    system(strcat(com1, SETTINGS.color)); // set color of cmd
    system(strcat(com2, SETTINGS.title)); // set title of cmd
    *pMAXCHARS = atoi(SETTINGS.maxchars);

    // cleanup

    fclose(fp);
    free(color);
    free(title);
    free(maxchars);

    return 0; // success
}

Progsets.txt:

COLOR=$0a;
TITLE=$Typify!;
MAXCHARS=$10000;

编辑: 这里是 size() 函数的定义。因为我只是在处理 ASCII 文本文件,所以我假设每个字符都是一个字节,并且可以通过计算字符数来计算文件大小(以字节为单位)。有什么可疑的吗?

尺寸():

int size(FILE* fp)
{
    int size = 0;
    int c;

    while ((c = fgetc(fp)) != EOF)
    {
        size++;
    }

    return size;
}

【问题讨论】:

  • 我在你的程序中没有看到任何fscanf
  • 是的。标题错别字,不好意思。它应该是“fgets() 没有从文本文件中读取?”
  • 你的 mallocing char * as char **,不检查 mallocs 的返回,并且可能需要在获取大小后回退文件
  • 我认为它怀疑错误导致文件在size(fp)结束。

标签: c null load settings gets


【解决方案1】:

问题在于您使用了size() 函数。它在文件句柄上反复调用fgetc(),直到到达文件末尾,增加一个值以跟踪文件中的字节数。

这不是一个的方法(虽然我确信有更好的方法不涉及低效的基于字符的 I/O)但它确实有一个致命 你似乎忽略了的缺陷。

在你调用它之后,你已经将文件一直读取到最后,以便进一步读取,例如:

fgets(color, ARR_SIZE, fp);

将简单地失败,因为您已经在文件的末尾。在从 size() 返回之前,您可能需要考虑类似 rewind() 的内容 - 这会将文件指针放回文件的开头,以便您可以再次读取它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-29
    • 2020-06-09
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多