Вы не представили бы что-то такое же, как открытие файла с использованием стандартной библиотеки С++ для приложения Windows, было сложно... но похоже, что это так. В Unicode я имею в виду UTF-8, но я могу конвертировать в UTF-16 или что-то еще, точка получает экземпляр экземпляра из имени файла Unicode. Прежде чем я взломаю собственное решение, есть ли здесь предпочтительный маршрут? Особенно кросс-платформенный?
Как открыть std:: fstream (ofstream или ifstream) с именем файла Unicode?
Ответ 1
Стандартная библиотека С++ не поддерживает Unicode. char
и wchar_t
не обязательно должны кодироваться в кодировке Юникод.
В Windows wchar_t
есть UTF-16, но нет прямой поддержки имен файлов UTF-8 в стандартной библиотеке (тип данных char
не является Unicode в Windows)
В MSVC (и, следовательно, в Microsoft STL) предоставляется конструктор для потоков, который принимает имя файла const wchar_t*
, что позволяет создать поток как:
wchar_t const name[] = L"filename.txt";
std::fstream file(name);
Однако эта перегрузка не указана стандартом С++ 11 (это гарантирует только наличие версии char
). Он также не присутствует в альтернативных реализациях STL, таких как GCC libstdС++ для MinGW (-w64), начиная с версии g++ 4.8.x.
Обратите внимание, что так же, как char
в Windows не UTF8, на других ОС wchar_t
может быть не UTF16. Поэтому в целом это вряд ли будет переносимым. Открытие потока с именем wchar_t
не определено в соответствии со стандартом, а указание имени файла в char
может быть затруднено, потому что кодировка, используемая char, варьируется между OS'es.
Ответ 2
Начиная с С++ 17, существует кроссплатформенный способ открытия std::fstream с именем файла Unicode с использованием перегрузки std::filesystem :: path. До С++ 20 вы можете создать путь из строки UTF-8 с помощью std::filesystem :: u8path. Пример:
std::ofstream out(std::filesystem::u8path(u8"こんにちは"));
out << "hello";
После С++ 20 вы можете создать путь, передав UTF-8 в конструктор: std::filesystem::path(u8"こんにちは")
(u8path не рекомендуется).
Ответ 3
В текущих версиях Visual С++ у std:: basic_fstream есть метод open()
, который принимает wchar_t * в соответствии с http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx,
Ответ 4
Используйте std::wofstream
, std::wifstream
и std::wfstream
. Они принимают unicode имя файла. Имя файла должно быть wstring
, массив wchar_t
s, или перед текстом должен иметь макрос _T()
или префикс L
.
Ответ 5
Посмотрите Boost.Nowide:
#include <boost/nowide/fstream.hpp>
#include <boost/nowide/cout.hpp>
using boost::nowide::ifstream;
using boost::nowide::cout;
// #include <fstream>
// #include <iostream>
// using std::ifstream;
// using std::cout;
#include <string>
int main() {
ifstream f("UTF-8 (e.g. ß).txt");
std::string line;
std::getline(f, line);
cout << "UTF-8 content: " << line;
}
Ответ 6
Если вы используете Qt, смешанный с std::ifstream
:
return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));