c – fgetws loading string with \0 after every character


For fun, and for practice, I’m trying to update an abandoned Open Source desktop single-player game, written in C, beginning by getting it working in Visual Studio 2019.

Here’s what I think is all the the relevant code (it does use allegro 4, but I can’t think that’s relevant to this particular problem):

typedef enum MaxLengths {
    ML_CHARNAME = 24
    , ML_CHARCNT = 24
};

FILE *inputfile;
char charlist[ML_CHARCNT][ML_CHARNAME];

void trim_trailing_chars(char* str, const char* chars_to_trim) {
    //see https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input
    str[strcspn(str, chars_to_trim)] = 0;
}

int load_charlist()
{
    errno_t err;
    char tempstr[48]; //ML_CHARNAME * 2, to be on the safe side
    int i = 0;

    err = fopen_s(&inputfile, "Saves//charlist.dat", "r, ccs=UTF-8");

    if (!inputfile) {
        set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
        allegro_message("Can't open Saves\\charlist.dat.  Exiting.");
        return 1;
    }

    charcount = 0;
    while (!feof(inputfile) && !ferror(inputfile))
    {
        if (fgetws(tempstr, _countof(tempstr), inputfile) != NULL)
        {
            trim_trailing_chars(tempstr, "\r\n");
            if (strcmp(tempstr, "none") != 0)
            {
                ++charcount;
                strcpy_s(charlist[i], _countof(charlist[i]), tempstr);
                i++;
            }
        }
        strcpy_s(tempstr, _countof(tempstr), "");
    }
    err = fclose(inputfile);

}

int main(int argc, char* argv[])
{
    load_charlist();
}

Saves\charlist.dat is a UTF-8 data file (according to NP++), with crlf characters terminating each line. Here’s the full file, as it stands right now. This is copied from my old gameplay, which does work (with a few minor bugs, hence me trying to update it. The original game used fscanf, but I’d prefer to use fgets or fgetws):

Rema
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none
none

When I run the code, the character names it returns in charlist are: “R”, “n”, “n”, ….

When stepping through, a watch on the tempstr variable reveals that, for some reason, every other character in the array (after fgets does its thing), is \0.

The immediate window also bears this out. Here’s some output from when I was troubleshooting:

? tempstr
0x008fe5e0 "R"
    [0]: 82 'R'
    [1]: 0 '\0'
    [2]: 101 'e'
    [3]: 0 '\0'
    [4]: 109 'm'
    [5]: 0 '\0'
    [6]: 97 'a'
    [7]: 0 '\0'
    [8]: 10 '\n'
    [9]: 0 '\0'
    [10]: 0 '\0'
    [11]: 0 '\0'
    [12]: -52 'Ì'
    [13]: -52 'Ì'
    [14]: -52 'Ì'
    [15]: -52 'Ì'
    [16]: -52 'Ì'
    [17]: -52 'Ì'
    [18]: -52 'Ì'
    [19]: -52 'Ì'
    [20]: -52 'Ì'
    [21]: -52 'Ì'
    [22]: -52 'Ì'
    [23]: -52 'Ì'
    [24]: -52 'Ì'

Anybody know why it’s doing this, and how to fix it? Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *