Search code examples
arrayscfilememorystrcat

How to load 3 values from a file into a char* array (C)?


I tried implementing a Function which opens a obj file and loops over every character in one line starting from the second character, because the first and the second character are just "v " which stands for vertex. Somehow I get an acces violation error. Here is the code:

bool LoadFromObjectFile(char* filepath) {
    FILE* pF;
    fopen_s(&pF, filepath, "r");
    if (pF == NULL)
        return false;

    char buffer[128];

    while (fgets(buffer, sizeof(buffer), pF) != NULL) {
        if (buffer[0] == 'v') {
            int currCoord = 0;
            char* vCoords[3] = { "", "", ""};

            for (int i = 2; i < sizeof(buffer); i++) {
                if (buffer[i] == ' ') {
                    currCoord++;
                    continue;
                }

                strcat_s(vCoords[currCoord], sizeof(&buffer[i]), &buffer[i]);
            }
        }
    }

    printf("%s\n", buffer);
    fclose(pF);

    return true;
}

I tried to use the strcat function to add the current character to one of the vCoords. I thought it's going to work immediately but I get an error and I have no idea why.


Solution

  • char* vCoords[3] = { "", "", ""};
    

    You've got yourself a nice array of three pointers to string literals.

    strcat_s(vCoords[currCoord], sizeof(&buffer[i]), &buffer[i]);
    

    You are trying to modify a string literal here. This is not allowed. Even if you could modify a string literal, which you can't, you are using sizeof(&buffer[i]) which is totally wrong at several levels, and your string literals are big enough to contain an empty string and nothing else.

    It isn't actually clear at all what you are trying to do. The loop doesn't seem to have any visible effect. You just print the last line of the file after the loop. That's all your function does.

    If you, as my guess is, want to pull three space-separated tokens out of each line, you do this with the strtok function, in this approximate fashion (caveat, untested code):

    char vCoords[3][128];
    char* start = buffer + 2;
    char* token = strtok(buffer, " ");
    for (int token_idx = 0; token_idx < 3 && token != NULL, ++token_idx)
    {
       strcpy(vCoords[token_idx], token);
       token = strtok(NULL, " ");
    }
    

    Of course you want to do something with vCoords, otherwise you could just replace the function with an empty pair of braces.