Как открыть std :: fstream (ofstream или ifstream) с именем файла в юникоде? - PullRequest
46 голосов
/ 05 мая 2009

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

Ответы [ 6 ]

55 голосов
/ 05 мая 2009

Стандартная библиотека 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, варьируется в зависимости от операционной системы.

3 голосов
/ 23 февраля 2019

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

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

После C ++ 20 вы можете создать путь, передав UTF-8 в конструктор: std::filesystem::path(u8"こんにちは") (путь u8 будет устаревшим).

3 голосов
/ 05 мая 2009

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

2 голосов
/ 14 июля 2016

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

1 голос
/ 15 октября 2018

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

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
1 голос
/ 30 января 2018

Взгляните на 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...