Как в файл записать строку в кодировке UTF-8?

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Файл бинарный, ни с какими потоками не связан, а открыт функцией CreateFile, но некоторые поля в нём должны быть текстовыми в кодировке UTF-8. Как лучше объявить константу для записи такого поля?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Что ты подразумеваешь под "полями файла"?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Используй сериализацию. Это позволяет сохранять в один бинарный файл разнородные данные. Здесь основной принцип таков: сначала в файл записывается размер данных, а потом сами данные, за ними могут идти следующие блоки данных и т.д. В начале файла обычно размещается заголовочная структура с информацией о хранимых данных, в которой записаны размеры бинарных блоков, их смещения внутри файла и прочее.
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

Про сериализацию верно сказано. Только от себя хочу добавить, что для этого не нужно самому изобретать велосипеды. Есть готовые библиотеки на С++, в которых механизм сериализации уже реализован.
Поумнеть несложно, куда труднее от дури избавиться.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Что ты подразумеваешь под "полями файла"?
А что такое тег Вы в данном контексте понимаете? Поле - почти то же самое, но имеет фиксированную разрядность.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

WinMain писал(а):Используй сериализацию. Это позволяет сохранять в один бинарный файл разнородные данные.
Вопрос не в том, как превратить осмысленные данные в сырые байты, а в том, как лучше объявить константу, если с неё требуется писать UTF-8. Не строку символов типа wchar_t в его внутреннем представлении, а именно UTF-8. Но чтоб её не требовалось скармливать функции WideCharToMultiByte, а можно было сразу привести её адрес к указателю на void и результат напрямую без каких либо преобразований скормить функции WriteFile.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

WinMain писал(а):Здесь основной принцип таков: сначала в файл записывается размер данных, а потом сами данные, за ними могут идти следующие блоки данных и т.д.
Нет. В начале идёт заголовок, содержащий маркеры формата и версии. Тот же заголовок содержит смещение подзаголовка, размер которого зависит от версии формата, а там уже располагаются смещения данных и поля, по которым можно вычислить их количества. Иначе рискуешь прочитать полный бред, когда тебе подсунут файл чужой прилады, но по непонятной причине с тем же расширением. А так в разных форматах маркеры не совпадают, читаешь сначала маркер, сравниваешь его с эталоном и если файл чужого формата, то высвечиваешь окошко с мессагой, что формат файла приладе не известен. Но прилада работает не с абстрактным "документом", а с объектом, ни маркера файлового формата, ни файловых смещений как раз не содержащим за ненадобностью.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

В С++03 никак нельзя такое провернуть, так как язык поддерживает только узкие и широкие строковые литералы.

Начиная с 11 стандарта, можно дополнительно объявлять строковые литералы некоторых кодировок прямо в коде. Для UTF-8 это выглядит так:

Код: Выделить всё

u8"I'm a UTF-8 string."
Подробнее здесь в разделе Новые строковые литералы.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Decoder писал(а):Про сериализацию верно сказано. Только от себя хочу добавить, что для этого не нужно самому изобретать велосипеды. Есть готовые библиотеки на С++, в которых механизм сериализации уже реализован.
Почитайте ка энциклопедию графических форматов, а потом прикиньте сложность задачи подружить какую то там универсальную библиотеку с любым файловым форматом и с внутренним представлением рисунка. Если сложность пользования инструмента не уступает "велосипеду", то нафиг он нужен? А если она специализирована, то ориентирована на конкретные форматы и для создания любого нового формата не применима. То есть имеем:
1. Зачем изобретать армату, когда есть кисть и краски?
2. Зачем изобретать армату, когда уже есть готовые Т 34-85, ИС 2, КВ 1 и А 32?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Ответить