Как открыть std :: fstream (ofstream или ifstream) с именем файла в юникоде?

StackOverflow https://stackoverflow.com/questions/821873

  •  03-07-2019
  •  | 
  •  

Вопрос

Вы не могли бы представить что-то столь же простое, как открытие файла с использованием стандартной библиотеки C ++ для приложения Windows было сложным делом ... но, похоже, это так. Под Unicode здесь я подразумеваю UTF-8, но я могу преобразовать в UTF-16 или что-то еще, суть в том, чтобы получить экземпляр ofstream из имени файла Unicode. Прежде чем я выберу свое собственное решение, есть ли здесь предпочтительный маршрут? Особенно кроссплатформенный?

Это было полезно?

Решение

Стандартная библиотека C ++ не поддерживает Unicode. char и wchar_t не обязательно должны быть кодировками Unicode.

В 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);

Однако эта перегрузка не указана в стандарте C ++ 11 (она гарантирует только наличие версии на основе char ). Он также отсутствует в альтернативных реализациях STL, таких как GCC libstdc ++ для MinGW (-w64), начиная с версии g ++ 4.8.x.

Обратите внимание, что точно так же, как char в Windows не является UTF8, в других ОС wchar_t может не быть UTF16. Так что в целом это вряд ли будет портативным. Открытие потока с именем wchar_t не определено в соответствии со стандартом, и указание имени файла в char s может быть затруднено, поскольку кодировка, используемая char, варьируется в зависимости от ОС ' х годов.

Другие советы

В текущих версиях Visual C ++ std :: basic_fstream есть метод open () , который принимает wchar_t * в соответствии с http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx .

Начиная с C ++ 17, существует кроссплатформенный способ открыть std :: fstream с именем файла Unicode, используя перегрузка std :: filesystem :: path . До C ++ 20 вы можете создать путь из строки UTF-8 с помощью станд :: файловая система :: u8path . Пример:

std::ofstream out(std::filesystem::u8path(u8"こんにちは"));
out << "hello";

После C ++ 20 вы можете создать путь, передав UTF-8 конструктору: std :: filesystem :: path (u8 " & # 12371; & # 12435; & # 12395; & # 12385; & # 12399; ") (путь u8 устарел).

Используйте std :: wofstream , std :: wifstream и std :: wfstream . Они принимают Unicode имя файла. Имя файла должно быть wstring , массивом wchar_t или оно должно иметь макрос _T () или префикс L перед текстом.

Просмотрите 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;
}

Если вы используете Qt, смешанный с std :: ifstream :

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top