简体   繁体   中英

fgets() not reading from a text file?

I have a function loadsets() (short for load settings ) which is supposed to load settings from a text file named Progsets.txt . loadsets() returns 0 on success, and -1 when a fatal error is detected. However, the part of the code which actually reads from Progsets.txt , (the three fgets() ), seem to all fail and return the null pointer, hence not loading anything at all but a bunch of nulls. Is there something wrong with my code? fp is a valid pointer when I ran the code, and I was able to open it for reading. So what's wrong?

This code is for loading the default text color of my very basic text editor program using cmd.

headers:

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

EDIT: Here is the definition of the size() function. Since I'm just working with ASCII text files, I assume that every character is one byte and the file size in bytes can be worked out by counting the number of characters. Anything suspicious?

size():

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

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

    return size;
}

The problem lies in your use of the size() function. It repeatedly calls fgetc() on the file handle until it gets to the end of the file, incrementing a value to track the number of bytes in the file.

That's not a bad approach (though I'm sure there are better ones that don't involve inefficient character-based I/O) but it does have one fatal flaw that you seem to have overlooked.

After you've called it, you've read the file all the way to the end so that any further reads, such as:

fgets(color, ARR_SIZE, fp);

will simply fail since you're already at the end of the file. You may want to consider something like rewind() before returning from size() - that will put the file pointer back to the start of the file so that you can read it again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM