0

I'm developing a Win32 application that has a configuration dialog where the user can specify file paths to things like the database root / working directory. Up until now, in testing, I've been using this functionality with relative file paths, as my file structure is not spread out too much. Also, my config.txt file, which is in the same directory as the .exe file, is loaded on startup, calling the std::ifstream constructor with a relative, hard-coded path.

As I'm newly working with the command line (allowing to drag files on the program's .exe file, therefore passing their paths), the path to the config.txt file somehow is not recognized as valid and my program (accordingly) throws an error upon this. Replacing the relative, hard-coded path with an absolute path won't fix this, because then, there's the problems with white spaces, backslashes (possibly German Umlaute in my user name too...).

Besides the problem with the config.txt path, I now have attempted to paste absolute paths from the address bar of Windows Explorer into the edit controls of my program's configuration dialog. However with these paths, I run into pretty much the same problems.

To round this up (and possibly further hint to the source of my problem), the same behaviour occurrs when I drag files on the .exe to pass their paths. Luckily, the paths (containing whitespaces) are quoted in the command line, so separation is easy, but after reading in, they behave just like the config.txt path and paths entered into the configuration dialog.

Long story short - I am looking for a way to convert paths from the command line or the address bar of Windows Explorer into valid arguments to the std::ifstream constructor. The issues dealt with here are common actually - the standard whitespaces, backslash and Umlaute (Unicode) things.

Here's a minimal example of reading in an absolute path from the dialog and trying to open a std::ifstream:

char path[256];
HWND hEditCtrl = GetDlgItem(hwndConfigurationDlg, IDC_CONFIG_EDITTEXT_DATABASE);
GetWindowText(hEditCtrl, path, sizeof(path));

// path contains something like
// "C:\Users\Firstname Lastname\Documents\2__Programming\Desktop\Gerät.txt"
// notice the whitespace, backslashes, German Umlaut.

std::ifstream ifstr(path, ios::in);
if (!ifstr.good()){
    MessageBox(NULL, "The file was not found at the specified path.",
                    "File Open Error", MB_OK);
}
Sam
  • 251
  • 1
  • 19
  • Most likely your problem is that your program doesn't handle being started in different working directories. Go ahead and put in a minimum code example. – HerrJoebob Jan 28 '15 at 18:01
  • What would you like the code example to contain? It's pretty much just recieving the text from an edit control that has an absolute path from Windows Explorer in it and trying to open a std::ifstream with that path. – Sam Jan 28 '15 at 18:03
  • @HerrJoebob What could be a reason for my program to not handle being started in different working directories? I mean, as long as file paths are absolute and valid, how does it matter where the exe is? – Sam Jan 28 '15 at 18:47
  • Does the path contain quotes too as shown above? – Jonathan Potter Jan 28 '15 at 18:57
  • No, not when the user enters the path. Can be added though. I don't know if the std::ifstream constructor takes paths with quotes. – Sam Jan 28 '15 at 19:13
  • Why are you using ANSI text? Do you need to support Windows 98? – David Heffernan Jan 28 '15 at 19:18
  • No you do not want quotes, it's just that your example above showed them. – Jonathan Potter Jan 28 '15 at 19:22
  • @DavidHeffernan I'm using ANSI? I'm not using it intentionally. How do you see that? I thought char is normal standard today ... – Sam Jan 28 '15 at 19:24
  • Windows native encoding is UTF-16. Held in wchar_t elements. You are using the Win 98 compatibility api. – David Heffernan Jan 28 '15 at 19:36
  • So if I'm using wchar_t, my paths can contain German Umlaute and all the ANSI symbols? That's strange to me, I've always been using plain char as it's applied in pretty much every tutorial I've seen :) – Sam Jan 28 '15 at 19:40
  • Pretty hard to imagine how an absolute path could fail. Working directory is not relevant. – David Heffernan Jan 28 '15 at 20:09
  • Nah, the paths themselves are correct, it has to be the backslash and whitespace stuff. I just thought there has to be like a standard function from the WinAPI or something to make it ready for the system() call. I couldn't find any information about the format of the paths to be passed into the std::ifstream constructor either ... – Sam Jan 28 '15 at 20:29
  • What can we say. If the system tells you that there's no such file, then you got the path wrong. But you should certainly stop using ANSI text. – David Heffernan Jan 28 '15 at 20:36
  • @DavidHeffernan Sorry, I'm not actually making any system() call. The std::ifstream constructor is all I send any path to. You mean I can basically just replace every 'char' with 'wchar_t'? Or isn't it as simple as that? – Sam Jan 28 '15 at 20:39
  • No it's not that simple. You might not be making the system call. The library is. But the C++ library isn't Unicode aware. Well, maybe the latest version is, I don't know. http://stackoverflow.com/questions/821873/how-to-open-an-stdfstream-ofstream-or-ifstream-with-a-unicode-filename – David Heffernan Jan 28 '15 at 20:47
  • The standard `std::basic_ifstream` does not support Unicode filenames. Non-ASCII characters are assumed to be in the current locale. So you may be encountering a conversion error, producing a filename that does not actually match the real file. However, Microsoft's version of `std::basic_ifstream` includes an additional non-standard constructor that accepts a UTF-16 filename as `wchar_t*`. You could use `MultiByteToWideChar()` to convert the user's Ansi text to UTF-16 yourself, or switch to Unicode-based edit fields so you can get the user's text as UTF-16 directly. – Remy Lebeau Jan 28 '15 at 21:34

0 Answers0