C++ и пути к файлам с национальными символами (возможно, с кодировкой utf8)

У меня есть кросс-платформенный код, и он должен использовать какой-то файл конфигурации. Все работает нормально, кроме случая, когда путь к имени файла конфигурации содержит символы, отличные от ANSI.

Для открытия / чтения файла использую std::ifstream. На платформе Windows (MSVC) решением является использование перегруженной версии std::ifstream, которая может принимать имя пути как wchar_t*, поэтому имя пути закодировано как utf16, и нет проблем с национальными символами в пути.

Но какое решение для систем NIX *? Насколько мне известно, все имена таких файлов закодированы с помощью UTF-8, и можно использовать char* в качестве указателя на строку. Например:

std::string path_name = ...; //assigning path name
std::ifstream fin(path_name.c_str());

Но как насчет c_str(), который возвращает постоянный указатель на строку имени файла, за которой следует терминатор null? Поскольку последовательность байтов UTF-8 может содержать нули как часть кодовых точек, такая строка может быть усечена.

Так что, пожалуйста, укажите мне, где я ошибаюсь, или предложите какое-нибудь портативное решение, если я в порядке))

Спасибо.

ifstream имеет конструктор, который принимает в качестве параметра std :: string - нет необходимости использовать c_str ().

user2100815 30.09.2018 20:52

UTF-8 не содержит нулей как часть кодовых точек. Текст UTF-8 заканчивается нулем, как текст ASCII.

Öö Tiib 30.09.2018 21:06

Не могли бы вы пояснить, что вы имеете в виду под "Все работает нормально, кроме случая, когда путь к имени файла конфигурации содержит символы, отличные от ANSI."? А почему вы думаете, что проблема в строке имени файла?

Christophe 30.09.2018 21:37

@ ÖöTiib UTF-8 должен использовать до четырех байтов на символ. Каждый байт многобайтовой последовательности содержит самый старший бит как 1. Итак, да, вы абсолютно правы - где нет нулевого байта в такой необработанной строке utf-8. Вот в чем я ошибался. Спасибо. Как я могу отметить ваш комментарий как ответ?

user1503944 30.09.2018 21:49

@NeilButterworth Позор мне. Я застрял на C++ 98) Начиная с C++ 11, где это std :: string версия конструктора std :: ifstream.

user1503944 30.09.2018 21:50

Вы можете ответь на свой вопрос.

zett42 30.09.2018 22:05

@ user1503944 UTF-8 supposed to use up to four bytes, per symbol. Не условное обозначение. Вы, наверное, думаете о кодовая точка. Символ может состоять из одной или нескольких кодовых точек (каждая из которых состоит из четырех кодовых единиц в UTF-8).

eerorika 30.09.2018 22:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
273
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

UTF-8 не содержит нулей как часть кодовых единиц. Байты в многобайтовых последовательностях должны иметь самый старший бит. Таким образом, текст UTF-8 может оканчиваться нулем, как текст ASCII.

Поэтому вы можете использовать path_name.c_str() в качестве имени файла в кодировке UTF-8.

Байты в строке UTF-8 известны как Единицы кода. Кодовые точки - это значения Unicode, которые UTF кодируют в кодовые единицы. В любом случае в UTF-8 есть нулевой байт - символ NUL, кодовая точка Unicode U+0000, которая закодирована в UTF-8 как байт 0x00 и, таким образом, может использоваться в качестве нулевого терминатора в строке с завершающим нулем.

Remy Lebeau 02.10.2018 03:09

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