Разница в кодировка chcp 1251/866/UTF-8/UTF-8-со спецификацией, а именно при сохранении разными программами

  • Автор темы Автор темы HotBeer
  • Дата начала Дата начала

HotBeer

Команда форума
Ассоциация VN/VIP
Модератор
Сообщения
446
Реакции
195
Всем доброго времени суток, решил сегодня побаловаться с чатом GPT, и не много себя словил на мысли на счет сохранения батниками разными программами в частности встроенным блокнотом windows 10 и популярного Notepad+, а так же о разницы встроенных блокнотом в разных ревизиях самой винды. Кто со мной знаком, знает что я перешёл на постоянную основу на win 10 может только 2-3 года назад и в эти несколько лет особо никаких задач не было, касаемо написания хоть каких либо пару строчек в cmd.

Вот достаточно просто батник:
CMD/BATCH:
@echo off
chcp 65001 > nul
set source="O:\ЖУРНАЛ-ВКС-2023.xls"
set destination="C:\backup\"

copy /Y /V "%source%" "%destination%"
pause
Он работает без проблем, но... а теперь вопросы:
1. До этого, если в батнике были какие либо проблемы с кириллицей, то я просто добавлял в начало chcp 1251 > nul, либо 866, но сейчас это не сработало, нужен был именно UTF 65001. Причем если пересохранять хоть в UTF/866/1251 именно Notepad+ батник не срабатывал, так как винда не видела источник set source="O:\ЖУРНАЛ-ВКС-2023.xls", а если зайти виндовым блокнотом и там пересохранить как UTF-8 со спецификацией, то батник видел источник и соответственно копировал в назначение, почему так?
2. Вопрос, каким образом блокноты сильно отличаются от версии винды?
3. В XP и в 2003 серверной винде я просто в блокноте ставил штатными средствами пересохранить как 866 и ни когда проблем не встречал?
4. Если зайти в cmd набрать chcp, то винда показывает "Текущая кодовая страница: 866", но при этом батник срабатывает, если только сохранить как chcp 65001 > nul

п.с. сразу не пинайте ничего в bat'е не делал с XP
 
Причем если пересохранять хоть в UTF/866/1251 именно Notepad+ батник не срабатывал
Если ты говоришь про Notepad++, то допустим в UTF/1251 ты еще мог пересохранить, а вот в 866 навряд ли, там нет такой функции на сколько мне известно (без плагинов). Такое умеет, например, AkelPad через меню Файл - Сохранить как. Я предполагаю, что ты мог спутать функционал Notepad++ меню - Кодировки - "Кодировка" и меню Кодировки - "Преобразовать в", из-за чего дальнейшие тесты получились некорректными.

Кодировки - Преобразовать в...: реально изменяет коды символов.
Кодировки - Кодировка...: не изменяет байты текста, а только его отображение на экране, как если бы ты смотрел на один и тот же текст под другой призмой.

Теперь по поводу исполнения самого батника.
Команда chcp заставляет терминал интерпретировать текст батника в нужной тебе кодировке. Т.е. если ты сохранил батник в кодировке UTF8, тогда и chcp нужно задавать как 65001, чтобы консоль понимала, что текст закодирован именно в этой кодовой странице. Если сохранил как ANSI, то chcp 1251. Сохранил как OEM, то chcp нужно задавать 866.

UTF8 - 65001
ANSI - 1251
OEM - 866

2. Вопрос, каким образом блокноты сильно отличаются от версии винды?
Начиная с Windows 10 стандартной кодировкой сохранения файла в блокноте стала UTF8, отсюда и все различия. Через меню Сохранить как... это можно поменять.

На счёт кодировки UTF16, консоль ее не поддерживала до Windows 10.
Начиная с Windows 10 build 1809 были подвижки с внедрением поддержки урезанного варианта UTF16, а именно UCS2.
На сколько успешно точно сказать не могу, я не особо с этим разбирался. Подробности есть в новости: Windows Command-Line: Unicode and UTF-8 Output Text Buffer
Помню, что была раньше галочка в настройках терминала в экспериментальном разделе. Сейчас уже не наблюдаю.
Могу только сказать, что на Win10-11 сейчас UCS2 на консоли вполне себя хорошо чувствует, если работать через C++, то:
C++:
#include <fcntl.h>
#include <io.h>

int main()
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    wprintf(L"法");
}
Получим в выводе китайский символ 法 вне зависимости от настроек системной локали.
До Windows 10 это решалось установкой специальных шрифтов и выставлением настроек системной локали для программ, не поддерживающих юникод, на Китайский и другие языки по необходимости. Либо довольствовались UTF8, но также требовалась замена стандартных шрифтов терминала на поддерживающие юникод.

По поводу спецификации BOM:
Если она указана, то Notepad++ обычно корректно все определяет. Если ее нет, то Notepad++ (и другие редакторы) могут соврать, и в статусной строке написать неверное название кодировки, на это нельзя ориентироваться, без BOM редактор включает свои умные алгоритмы в попытке распознать кодовую страницу через перебор символов в тексте и их сравнения с неким порогом вероятности. Надёжно можно определить только на глаз, открывая с разными параметрами Кодировки - "Кодировка" и проверяя, корректно ли читается русский текст.
По поводу батника, он НЕ поддерживает BOM. Нет автоматического распознавания, но и не обязательно упадёт при его наличии.

В завершение, вне зависимости от версии ОС или редактора, если правильно указываешь кодировку сохранения и соответствующую ей chcp в коде, то батник с текстом на русском будет нормально отрабатывать везде. В случае же с Notepad++ дополнительно следует обращать внимание, правильная ли кодировка распозналась при открытии файла.
 
Последнее редактирование:
Слегка не по теме, но хотелось бы уточнить по поводу Блокнота. Он до сих пор грешит добавлением пары бит в начало тела файла?
 
@ScriptMakeR, пара байт в начале файла - это обычно BOM. 0xFFFE - UTF16LE, 0xEFBBBF - UTF8. Можно посмотреть через 16-ричный редактор или Lister в Total Commander - Вид - Шестнадцатиричный. Это зависит от выбранной тобой кодировки при сохранении файла (с BOM или без). BOM помогает редакторам определить, в какой кодировке записан текст.
 
@Dragokas, спасибо.
Я просто вспомнил проблему, с которой столкнулся лет 15 назад. Я тогда увлекался сайтостроением на PHP для мобильных устройств. Тогда еще редактировал с кнопочной Nokia, и проблем не было. А вот когда появился компьютер, и я стал ваять в Блокноте, движок начал отказываться принимать файлы созданные в нем. Как выяснилось, проблема была как раз в этой паре байт. Тогда я и познакомился с Notepad++. Все думал, что это Блокнот плохой свое ненужное что-то добавляет. А это оказывается BOM - вполне себе нужная вещь:)
 
Бывают такие всякие разные глюки, когда сохраняешь одним редактором, он где-то в кеше запоминает изначальную кодировку (для N++ актуально), потом ты конвертируешь формат другим редактором, а N++ затем отказывается выполнять авто-определение и подставляет кодовую страницу из своего кеша. Тогда приходится вручную переключаться через меню Кодировки - Кодировка.
 
А по поводу распознавания кириллицы проходит без проблем, но команда не видит файл, если в его названии пробелы. Раньше лечилось просто кавычками, а сейчас есть панацея от этого?
 
И сейчас тоже кавычками. Покажи код, только это уже наверное не для этой темы.
 
CMD/BATCH:
@echo off
chcp 65001 > nul
set source="O:\ЖУРНАЛ-ВКС-2024.xls"
set destination="C:\backup\"

copy /Y /V "%source%" "%destination%"
pause
Если убрать "-" и поставить пробелы, то "источник не найден"
 
Назад
Сверху Снизу