РЕДАКТИРОВАТЬ: добавить ссылки на boost и wchar_t в конце сообщения и другое возможное решение для Windows.
Я мог бы воспроизвести почти одно и то же на Ubuntu и на Windows, даже не используя Boost (у меня его нет на моем окне Windows). Чтобы исправить это, мне просто нужно было преобразовать исходник в ту же кодировку, что и в системе, т.е. utf8 в Ubuntu и latin1 или iso-8859-1 в Windows.
Как я и подозревал, проблема исходит из строки fs::path file("äöü.txt");
. Поскольку кодировка файла отличается от ожидаемой, он более или менее читается как fs::path file("äöü.txt");
. Под вашим контролем вы обнаружите, что размер равен 10. Это полностью объясняет, что выходной файл имеет неправильное имя.
Подозреваю, что тест if (!fs::exists(file))
работает корректно, потому что либо буст, либо винда автоматически исправляет кодировку при вводе.
Итак, в Windows просто используйте редактор с кодовой страницей 1252, latin1 или iso-8859-1, и у вас не должно возникнуть проблем, если вам не нужно использовать символы вне этой кодировки. Если вам нужны символы за пределами Latin1, я боюсь, что вам придется использовать Unicode API Windows.
РЕДАКТИРОВАТЬ:
На самом деле Windows (> NT) изначально работает с wchar_t
, а не с char
. И неудивительно, что boost для Windows делает то же самое — см. ссылка на файловую систему библиотеки ускорения. Извлекать :
Для Windows-подобных реализаций, включая MinGW, path::value_type — это wchar_t. Встроенная локаль по умолчанию предоставляет аспект codecvt, который вызывает Windows MultiByteToWideChar или WideCharToMultiByte API с кодовой страницей CP_THREAD_ACP, если Windows AreFileApisANSI() имеет значение true ...
Таким образом, другое решение в Windows, которое позволило бы использовать полный набор символов Unicode (или, по крайней мере, подмножество, изначально предлагаемое Windows), состояло бы в том, чтобы указать путь к файлу как wstring
, а не как string
. В качестве альтернативы, если вы действительно хотите использовать имена файлов в кодировке UTF8, вам придется заставить локаль потока использовать UTF8, а не CP1252. Я не могу привести пример этого кода, потому что у меня нет бустера на моем окне Windows, на моем окне Windows работает старая XP и не поддерживается UTF8, и я не хочу публиковать непроверенный код, но я думаю, что в этом случае вы должен заменить
std::locale::global(boost::locale::generator().generate(""));
с чем-то вроде:
std::locale::global(boost::locale::generator().generate("UTF8"));
ВНИМАНИЕ: не проверено, поэтому я не уверен, является ли строка для генерации UTF8 или чем-то еще...
person
Serge Ballesta
schedule
09.05.2014
äöü.txt
, похоже, что литерал уже UTF8, за исключением того, чтоboost::fs::path
обрабатывает его так, как если бы это была CodePage 1252. Или, что более вероятно,boost::fs::path
вообще игнорирует кодировку и просто передает ОС , и ОС предполагает, что это кодовая страница 1252. - person Mooing Duck   schedule 30.04.2014fs::exists
работает, значит, ошибка должна быть вboost::fs::ofstream
. Я предполагаю, что это обнаруживает, что вы компилируете с помощью GCC и поэтому неправильно решаете передать ОС имя файла в кодировке UTF8. Это будет ошибка повышения. (Ответ был удален, но уточненная OP проблема идентична для широкого строкового литерала) - person Mooing Duck   schedule 30.04.2014äöü
не входят в исходный набор символов; попробуйте заменить их эквивалентными шестнадцатеричными литералами (я предполагаю, что вы имеете в виду версии этих символов, которые можно хранить в 8-битном символе). - person M.M   schedule 03.05.2014fs::exists
работает? Это действительно похоже на проблему с потоками файловой системы, поэтому я ищу решение без них или исправление для них. - person Mike M   schedule 03.05.2014int main() { std::cout << "äöü"; return 0; }
, что бы получилось на выходе? (включает опущено для ясности...) - person Serge Ballesta   schedule 09.05.2014