C ++ ifstream UTF8 первые символы - PullRequest
3 голосов
/ 25 июля 2010
  1. Почему файл, сохраненный как UTF8 (в Notepad ++), имеет этот символ в начале потока, который я открыл для него в моей программе на c ++?

    '╗┐

    Я понятия не имею, что это такое, я просто знаю, что его там нет, когда я сохраняю в ASCII. ОБНОВЛЕНИЕ: если я сохраню его в UTF8 (без спецификации), его там нет.

  2. Как проверить кодировку файла (ASCII или UTF8, все остальное будет отклонено;)) в c ++. Это именно эти персонажи?

Спасибо!

Ответы [ 5 ]

7 голосов
/ 25 июля 2010

Когда вы сохраняете файл как UTF-16, каждое значение составляет два байта.Разные компьютеры используют разные порядки байтов.Некоторые ставят самый старший байт первым, другие ставят младший байт первым.Unicode резервирует специальную кодовую точку (U + FEFF), называемую меткой порядка байтов (BOM).Когда программа записывает файл в UTF-16, она помещает эту специальную кодовую точку в начало файла.Когда другая программа читает файл UTF-16, она знает, что там должна быть спецификация.Сравнивая фактические байты с ожидаемой спецификацией, он может определить, использует ли считыватель тот же порядок байтов, что и записывающее устройство, или все байты должны быть поменяны местами.

При сохранении файла UTF-8нет никакой двусмысленности в порядке следования байтов.Но некоторые программы, особенно написанные для Windows, все еще добавляют спецификацию, закодированную как UTF-8.Когда вы кодируете кодовую точку спецификации как UTF-8, вы получите три байта: 0xEF 0xBB 0xBF.Эти байты соответствуют символам рисования прямоугольников в большинстве кодовых страниц OEM (это значение по умолчанию для окна консоли в Windows).

Аргумент в пользу этого состоит в том, что он помечает файлы как действительно UTF-8, в отличие от какой-то другой родной кодировки.Например, многие текстовые файлы в западной части Windows находятся на кодовой странице 1252. Пометка файла с помощью кодировки UTF-8 упрощает различие.

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

Если бы я писал программу, которая читает UTF-8, я бы проверял точно эти три байта в начале,Если они есть, пропустите их.

Обновление: Вы можете преобразовать U+FEFF ZERO WIDTH NO BREAK символов в U+2060 WORD JOINER за исключением начала файла [Gillam, Richard, Unicode Demysified , Addison-Wesley, 2003, p.108].Мой личный код делает это.Если при декодировании UTF-8 я вижу 0xEF 0xBB 0xBF в начале файла, я воспринимаю это как счастливый признак того, что у меня действительно есть UTF-8.Если файл не начинается с этих байтов, я просто продолжаю декодирование в обычном режиме.Если при декодировании позже в файле я сталкиваюсь с U + FEFF, я испускаю U + 2060 и продолжаю.Это означает, что U + FEFF используется только как спецификация, а не как ее устаревшее значение.

1 голос
/ 25 июля 2010

Что касается вашей второй точки, каждая допустимая строка ASCII также является допустимой строкой UTF-8, поэтому вам не нужно явно проверять ASCII. Просто прочитайте файл, используя UTF-8, если файл не содержит допустимой строки UTF-8, вы получите ошибку.

1 голос
/ 25 июля 2010

Не зная, что на самом деле представляют собой эти символы (т.е. без шестнадцатеричного дампа), это всего лишь предположение, но мое непосредственное предположение состоит в том, что то, что вы видите, является результатом взятия знака порядка байтов (BOM) ииз) кодировать его как UTF-8.Технически, вы не можете / должны делать это, но на практике это на самом деле довольно часто.

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

1 голос
/ 25 июля 2010

Почему файл, сохраненный как UTF8 , а не , имеет этот символ в начале [...] Я понятия не имею, что это такое, я просто знаю, что этонет, когда я сохраняю в ASCII.

Полагаю, вы ссылаетесь на метку порядка байтов (BOM) U+FEFF, символ пробела нулевой ширины, неразрывный пробел.Здесь (блокнот ++ 5.4.3) файл, сохраненный как UTF-8, имеет символы EF BB BF в начале.Я полагаю, что это то, что спецификация закодирована в UTF-8.

Как проверить кодировку файла

Вы не можете.Вы должны знать, в какую кодировку был записан ваш файл. Хотя кодированные в Unicde файлы могут начинаться с спецификации, я не думаю, что для этого есть требование.

0 голосов
/ 25 июля 2010

Полагаю, вы хотели спросить, почему у него такие персонажи? Эти символы, вероятно, являются меткой порядка байтов , которая согласно этой ссылке в UTF-8 является байтами EF BB BF.

Что касается знания, в какой кодировке находится файл, вы не можете получить его из самого файла. Вы должны знать это заранее (или спросить пользователя, который предоставляет вам файл). Для лучшего понимания кодирования без необходимости много читать, я настоятельно рекомендую Джоэла Спольски Абсолютный минимум каждому разработчику программного обеспечения, абсолютно, обязательно должен знать о Unicode и наборах символов (без извинений!)

...