Opening files on Windows using std::ifstream and filename provided by QFileDialog
-
Hi, I am trying to pass a filename to a 3rd party library which uses the functions in std::fstream to open the file. On Linux, this works well if I let the user choose the filename to open from
QFileDialog::getOpenFileName()
. On Windows, it also works, but only if there are no spaces and no extended characters in the filename.If the user chooses a file which is returned by QFileDialog as
C:/Users/Jörg Mustermann/Desktop/Some Folder/File Name.csv
how can I format this filename on Windows so that the external library can open it? If I tell the user to store the files in a folder with no spaces directly under the C:\ directory, it works fine. Merely replacing the "/" with the "\" directory separator doesn't seem to help.
The Windows OS is Windows 10, and the locale is German (Switzerland).
-
std::fstream does not care about spaces in filename but you have to use
\
instead/
-> https://doc.qt.io/qt-5/qdir.html#toNativeSeparators -
std::fstream does not care about spaces in filename but you have to use
\
instead/
-> https://doc.qt.io/qt-5/qdir.html#toNativeSeparators@Christian-Ehrlicher Thanks ... sorry, but I tried to type the "\" character in my first post, and it got swallowed. It is probably more a problem with the Umlaut in the path.
-
Please show some code.
-
Hi, I am trying to pass a filename to a 3rd party library which uses the functions in std::fstream to open the file. On Linux, this works well if I let the user choose the filename to open from
QFileDialog::getOpenFileName()
. On Windows, it also works, but only if there are no spaces and no extended characters in the filename.If the user chooses a file which is returned by QFileDialog as
C:/Users/Jörg Mustermann/Desktop/Some Folder/File Name.csv
how can I format this filename on Windows so that the external library can open it? If I tell the user to store the files in a folder with no spaces directly under the C:\ directory, it works fine. Merely replacing the "/" with the "\" directory separator doesn't seem to help.
The Windows OS is Windows 10, and the locale is German (Switzerland).
@Robert-Hairgrove try with:
QString filename = QFileDialog::getOpenFileName(...); QString nativeFilename = QDir::toNativeSeparators(filename);
-
Thanks for the suggestions, everyone. I was able to pinpoint the issue a little better in the meantime:
(1) You can have spaces in the path, but not extended characters such as "äöü";
(2) Windows 10 usingstd::ifstream::open()
seems equally happy with "/" as well as "\".In other words, both of these work OK, at least on Windows 10:
C:/Users/Robert Hairgrove/Desktop/Some Folder/Some File.csv C:\Users\Robert Hairgrove\Desktop\Some Folder\Some File.csv
But this doesn't:
C:\Users\Jörg Mustermann\Desktop\Some Folder\Some File.csv
I tried converting the filename with
QString::toLocal8Bit()
before passing it to the library, but in the debugger I could see that the "ö" was not converted correctly. And passing the filename directly (the library function calls forconst std::string &
) as UTF-8 does not work, either.Any other suggestions?
-
Thanks for the suggestions, everyone. I was able to pinpoint the issue a little better in the meantime:
(1) You can have spaces in the path, but not extended characters such as "äöü";
(2) Windows 10 usingstd::ifstream::open()
seems equally happy with "/" as well as "\".In other words, both of these work OK, at least on Windows 10:
C:/Users/Robert Hairgrove/Desktop/Some Folder/Some File.csv C:\Users\Robert Hairgrove\Desktop\Some Folder\Some File.csv
But this doesn't:
C:\Users\Jörg Mustermann\Desktop\Some Folder\Some File.csv
I tried converting the filename with
QString::toLocal8Bit()
before passing it to the library, but in the debugger I could see that the "ö" was not converted correctly. And passing the filename directly (the library function calls forconst std::string &
) as UTF-8 does not work, either.Any other suggestions?
@Robert-Hairgrove said in Opening files on Windows using std::ifstream and filename provided by QFileDialog:
I could see that the "ö" was not converted correctly.
It was for sure... Qt does not do the conversion wrong.
Use QFile instead ifstream. -
@Robert-Hairgrove said in Opening files on Windows using std::ifstream and filename provided by QFileDialog:
I could see that the "ö" was not converted correctly.
It was for sure... Qt does not do the conversion wrong.
Use QFile instead ifstream.@Christian-Ehrlicher I cannot use QFile because I am passing the filename to a 3rd party library which calls
std::ifstream
functions (perhaps you did not read my original message thoroughly?)Calling QString::toLocal8Bit() will convert "ö" etc. to UTF-8 on Linux correctly, but not on Windows ... these Unicode characters show up in the debugger of Qt Creator as illegal Unicode characters, at least on my system.
I found this, and it looks like I am stuck if the user insists on saving the input files in a path containing extended characters:
https://newbedev.com/how-to-open-an-std-fstream-ofstream-or-ifstream-with-a-unicode-filename -
I also noticed that using "/" as directory separator has been working fine with
std::fstream
under all versions of Windows for a long time (at least since 2009, I believe). -
@Christian-Ehrlicher I cannot use QFile because I am passing the filename to a 3rd party library which calls
std::ifstream
functions (perhaps you did not read my original message thoroughly?)Calling QString::toLocal8Bit() will convert "ö" etc. to UTF-8 on Linux correctly, but not on Windows ... these Unicode characters show up in the debugger of Qt Creator as illegal Unicode characters, at least on my system.
I found this, and it looks like I am stuck if the user insists on saving the input files in a path containing extended characters:
https://newbedev.com/how-to-open-an-std-fstream-ofstream-or-ifstream-with-a-unicode-filename@Robert-Hairgrove I don't think you will get that working, without modifying the dll.
As a last resort, you could use QFile and QStandardPaths and copy the file to a temp/appdata location and pass the new simplified path to the dll
-
@Christian-Ehrlicher I cannot use QFile because I am passing the filename to a 3rd party library which calls
std::ifstream
functions (perhaps you did not read my original message thoroughly?)Calling QString::toLocal8Bit() will convert "ö" etc. to UTF-8 on Linux correctly, but not on Windows ... these Unicode characters show up in the debugger of Qt Creator as illegal Unicode characters, at least on my system.
I found this, and it looks like I am stuck if the user insists on saving the input files in a path containing extended characters:
https://newbedev.com/how-to-open-an-std-fstream-ofstream-or-ifstream-with-a-unicode-filename@Robert-Hairgrove said in Opening files on Windows using std::ifstream and filename provided by QFileDialog:
these Unicode characters show up in the debugger of Qt Creator as illegal Unicode characters, at least on my system.
Because it's not utf-8 but your current locale.
There is nothing Qt can do here - fix your library to properly handle non-latin characters in the current locale or in utf-8 as @J-Hilk already said.
-
@Robert-Hairgrove I don't think you will get that working, without modifying the dll.
As a last resort, you could use QFile and QStandardPaths and copy the file to a temp/appdata location and pass the new simplified path to the dll
@J-Hilk Thank you. Fortunately, this is a source-code library, so no DLL to worry about.
There might be an equivalent function taking a memory buffer I could use, in which case I could let QFile open the file, as suggested by @Christian-Ehrlicher.
Otherwise, copying the file to a non-Unicode path seems to be the only way.