c++stringcharfilenames

Changing path filename produces incorrect results on some computers. C++


I am getting a file path and then attempting to replace the filename with another. My code works correctly on one computer, but not on another.

Here is my code:

FILE* SETTINGS_FILE;
char value[255];
char error[255];
char directory[255];
char file[255];
char* pos;
A_char pluginFolderPath[AEFX_MAX_PATH];


// READ LICENSE FILE IF AVAILABLE
PF_GET_PLATFORM_DATA(PF_PlatData_EXE_FILE_PATH_DEPRECATED, &pluginFolderPath);
strcat(pluginFolderPath, "\n");
pos = strrchr(pluginFolderPath, 0x5C);
if (pos != NULL) strcpy(file, pos + 1); 
strcpy(directory, "");
strncpy(directory, pluginFolderPath, strlen(pluginFolderPath) - strlen(file));  // strip file extension and counter
strcat(directory, "dofpro_ae.lic");

On the incorrect computer, this is what it displays:

Garbled Path

You can see it is adding a square character at the beginning of the filename, right before the 'd'.

Any ideas why this is happening, and why it works one computer but not another?

I am then trying to load the file but of course, it cannot find it due to the added garbled character.

Additionally, is there any easier / cleaner way to do this?

Thanks


Solution

  • strncpy does not guarantee null termination. To quote the reference linked above

    If count is reached before the entire array src was copied, the resulting character
    array is not null-terminated.
    

    On the other hand the next line of code uses strcat which depends in it's arguments being null terminated. This is where your code is bugged.

    The smallest change you could make is to ensure that the entire directory array is filled with null bytes before you start your string manipulation

    char directory[255]{};
    

    This means the fact that strncpy may not (does not in your case) add a null byte is not a problem because you have already filled the array with null bytes.

    A better approach would be to learn how to use C++ strings and/or the C++ filesystem library. C++ strings are less error prone than C strings and the std::filesystem::path class is designed for exactly the kind of operations you are performing here