0

I am trying to read and write to files with UTF-8 file names such as files with Arabic or Persian names ("سلام.jpg") in C++. I am using the following code and it works fine on *nix systems (I checked it up on Android NDK). But it fails on Windows. This code snippet just tries to read the length of the file via tellg but on Windows it tells that file isn't open and tellg returns -1. I am using QT MingW so the VS open doesn't apply for me.

QString inFileAdd)
this->inFileAdd=inFileAdd;

ifstream infile;
infile.open(this->inFileAdd.toUtf8().constData(),ios::binary|ios::in|ios::ate);
infile.seekg (0, infile.end);
cout<<"is open: ";
if(infile.is_open()){
cout<<"true"<<endl;
}else{
cout<<"false"<<endl;
}
this->size=infile.tellg();
cout<<this->inFileAdd.toUtf8().constData()<<endl<<"file Len:"<<this->size<<endl;
this->fileContent=nullptr;
infile.close();
NewUser
  • 87
  • 12

1 Answers1

1

ifstream (and ofstream) simply does not support UTF-8 file paths on Windows 1.

However, at least in Visual Studio, they have non-standard constructors (and open() overloads) that accept wchar_t* file paths, so you can convert your UTF-8 to UTF-16 (or, in your case, just use this->inFileAdd.toStdWString().c_str() instead) to open files that use Unicode paths/names.

1: Windows 10 has experimental support for UTF-8 as a user locale. Programs can manually opt-in to enable UTF-8 in ANSI-based APIs, like CreateFileA(), which ifstream/ofstream are likely to use internally.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I already tried `this->inFileAdd.toStdWString().c_str()`. It works even with `.toStdString` in *nix systems but it fails on windows. I am using QT MinGW. Is there any option available for me? – NewUser May 17 '21 at 22:07
  • Sounds like `std::ifstream`/`std::ofstream` in MinGW do not support opening files using `wchar_t*` strings. You might consider [using `Boost::nowide::ifstream`](https://stackoverflow.com/a/48518953/65863) instead. Or else construct a [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path) from your `QString` and then [construct the `std::ifstream`/`std::ofstream` from that `path`](https://stackoverflow.com/a/54842261/65863) (though, 1 person had a problem with that). – Remy Lebeau May 17 '21 at 22:42
  • `std::ifstream` doesn't support `path` neither. I'll try `boost`. – NewUser May 18 '21 at 07:39