0

I am currently programming a patching application for my game. As i am used to program with Java its hard for me to get along with C++, the patcher has to be wridden in C++ unfortunately, in Java i could do this in 5 minutes but a new language. . . not so much.

This is my current Code to create the folders i need:

#include <windows.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    //Set the Strings the Patcher needs.
    string DNGDirectory = "C:\\dnGames";
    const char* DDDirectory = "C:\\dnGames\\DuelistsDance";

    //Create directories if they don't exist yet.
    if (CreateDirectory(DNGDirectory.c_str(), NULL) || ERROR_ALREADY_EXISTS == GetLastError())
    {
        if (CreateDirectory(DDDirectory.c_str(), NULL) || ERROR_ALREADY_EXISTS == GetLastError())
        {
            cout << "Directories successfully created." << std::endl;
        }
    }

    return 0;
}

One time i use string for the variable, because this was in the example code i picked out from Google (Create a directory if it doesn't exist), but i get the error "Das Argument vom Typ ""const char "" ist mit dem Parameter vom Typ ""LPCWSTR"" inkompatibel." (Should be the argument of type ""const char" is incompatible with the parameter of type ""LPCWSTR"" in english) I tried to fix it by using "const char*" as type, but this gets me the error "Der Ausdruck muss einen Klassentyp aufweisen." (They expression must have a class type). Does anyone know how to fix this? I am using Visual Studio 2019 for this.

RAVN Mateus
  • 560
  • 3
  • 13
  • 2
    How are you calling `.c_str()` on a `const char*`??? – Object object Apr 03 '20 at 13:32
  • So, would it be possible to fix the program by removing .c_str() and changing the type to sting? – RAVN Mateus Apr 03 '20 at 13:36
  • 1
    Go back to using `std::string`. Changing to `const char*` is a step backwards. The error is because `c_str()` is a `const char *` but the function expects something else. I bet your project is configured to use unicode. Try `CreateDirectoryA` to see what happens. If that works, consider turning off unicode or using a wide string type. – François Andrieux Apr 03 '20 at 13:37
  • This may help: https://stackoverflow.com/questions/6858524/convert-char-to-lpwstr – stark Apr 03 '20 at 13:37
  • The problem is LPCWSTR is a weird Windows type not the same as a string or char *. – stark Apr 03 '20 at 13:38
  • Thanks for the comments, i could fix the problem by using CreateDirectoryA, but changing the project setting to not use unicode anymore dealt with the errors. I guess stark is right about LPCWSTR type beiing garbage. (Or at least i also cant see any use in it) – RAVN Mateus Apr 03 '20 at 14:06

2 Answers2

1

Since C++17 (and to a lesser extent 14) we can use std::filesystem (std::experimental::filesystem in C++14) to manipulate files and create directories.

For example in your case:

...
std::filesystem::path DDDirectory("C:\\dnGames\\DuelistsDance"); 

try {
  std::filesystem::create_directories(DDDirectory); // Creates all the directories needed, like mkdir -p on linux

// Success here

} catch(std::filesystem::filesystem_error& e) {
  // Handle errors here
}

This will make handling of your errors cleaner and your code cross-platform (although you will have to change the path, but std::filesystem::path turns / into \\ on windows anyway). It also makes your code easier to read and as you can see, much much shorter.

Object object
  • 1,939
  • 10
  • 19
  • Unlucky for me, i think Visual Studio doesnt like filesystem, i get the error "a name followed by :: has to be a class- or namespacename despite #import (which does not generate an error itself). Do you know how to fix this? – RAVN Mateus Apr 03 '20 at 13:54
  • Hmm... does `std::experimental::filesystem` work (your on msvc 2019 so it shouldn't), and where does the error occure? – Object object Apr 03 '20 at 14:14
  • after googleing i also tried the experimental and, no it didnt work. The errors occur at any point where the word filesystem is mentioned (in the creation of dddirectory under the try and in the catch()) and the error at catch is "the handler requires an exception declaration" the other 2 are what i mentioned before EDIT: if i do not import vs tells me to import filesystem but after autoimport it also wont recognize the std::filesystem – RAVN Mateus Apr 03 '20 at 14:20
  • Oh my bad, my catch statement was not actually legal code :D see if it works with the `& e` added – Object object Apr 03 '20 at 14:21
  • Now the std:: is not red anymore, the filesystem still is and it now says namespace std has no member filesystem_error. the other filesystem stuff is still red. – RAVN Mateus Apr 03 '20 at 14:28
  • i expect it is some bug within visual studio, I have already uninstalled VS one time because in the company i had an 10 week internship at it created so many bugs they searched for a new IDE – RAVN Mateus Apr 03 '20 at 14:30
  • Ugh i need to sleep, ok sorry again but i missed the `filesystem` part of the name, `std::filesystem::filesystem_error` is right (i kept reading it as that until you pointed it out too \*eyeroll*) – Object object Apr 03 '20 at 14:30
  • perfect, i guess the code is usually working like this because now all 3 std::filesystem::somethings have the same error. VS says no. – RAVN Mateus Apr 03 '20 at 14:32
  • Yes thats my import, i implemented it after reading https://learn.microsoft.com/de-de/cpp/standard-library/filesystem?view=vs-2019 – RAVN Mateus Apr 03 '20 at 14:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210878/discussion-between-ravn-mateus-and-lonesome-paradise). – RAVN Mateus Apr 03 '20 at 14:36
0

In case someone reads this and has the same problem, this is the final fix:

  • change project settings to not use unicode anymore
  • change variables to const char* DNGDirectory = "C:\\dnGames";
  • use CreateDirectory() and remove .c_str() after the variable name

Thanks for the comments and the alternate solution with std::filesystem!

RAVN Mateus
  • 560
  • 3
  • 13