Что нового

Кодировка для IniWrite

winkot

Новичок
Сообщения
188
Репутация
0
Функция
Код:
IniWrite

записывает файл (если нет русских символов) в кодировке UTF8. Если русские символы есть, то в ANSI. Можно ли сделать так, что бы всегда ini файл записывался в кодировке ANSI?
 

InnI

AutoIT Гуру
Сообщения
4,949
Репутация
1,443
Данный код действительно выводит 256.
Код:
IniWrite("test.ini", "test", "test", "test")
$Enc = FileGetEncoding("test.ini")
ConsoleWrite($Enc & @CRLF) ; 256 (UTF8 without BOM)

Но для латиницы UTF8 без BOM - это ANSI.
 

AZJIO

Меценат
Меценат
Сообщения
2,891
Репутация
1,195
IniWrite пишет либо в ANSI либо в UTF16. И никогда в UTF8. Если редактор воспринимает однобайтовый англ. текст как UTF8, а добавление русских символов определяется как ANSI, то это проблема редактора. Возможно он настроен изначально на UTF8 по умолчанию, то наличии русских символов в кодировке ANSI мешает ему думать что это UTF8. При наличии только англ букв текст в UTF8 и ANSI выглядит одинаково, так как оба варианта используют символы ниже 127.
 
Автор
W

winkot

Новичок
Сообщения
188
Репутация
0
Но для латиницы UTF8 без BOM - это ANSI.
Дело в том, что если INI файл записан в UTF8 и не имеет русских букв, то все хорошо. IniRead его легко читает. Но вот если в файле есть русские буквы, то все. IniRead его прочитать не может. И только после перекодировки в ANSI его сможет прочитать. Поэтому и хотелось бы, что бы файл сразу кодировался в ANSI и читался с любыми (русскими и не русскими) символами.
Сообщение автоматически объединено:

IniWrite пишет либо в ANSI либо в UTF16.
Тем не менее
Данный код действительно выводит 256.
 

InnI

AutoIT Гуру
Сообщения
4,949
Репутация
1,443
Ну не работают ini-функции с utf8. IniWrite всегда пишет в ansi. И латиницу и кириллицу. Если вы создали/сохранили файл с кириллицей в uft8 без bom каким-то редактором, то IniRead конечно его не прочитает.

Ещё раз повторяю. 256 - это utf8 без bom, который для латиницы полностью совпадает с ansi.
 
Автор
W

winkot

Новичок
Сообщения
188
Репутация
0

InnI

AutoIT Гуру
Сообщения
4,949
Репутация
1,443
Файл test.ini получился в кодировке UTF8
Попробуем ещё раз. Полученный файл содержит коды символов до 127 включительно. Данные коды соответствуют символам таблиц и ANSI и UTF8. Из двух кодировок AutoIt выбирает UTF8. Поэтому и выводит 256.
А если файл будет с кириллицей, то это уже будет однозначно ANSI, потому что коды символов кириллицы в таблицах ANSI и UTF8 не совпадают.
Код:
IniWrite("test.ini", "тест", "тест", "тест")
$Enc = FileGetEncoding("test.ini")
ConsoleWrite($Enc & @CRLF) ; 512 (ANSI)


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

InnI

AutoIT Гуру
Сообщения
4,949
Репутация
1,443
это означает, что файл записан в UTF8
Это означает, что AutoIt из двух одинаковых таблиц кодировок выбрал utf8. Это началось с версии 3.3.14. До этой версии данный код выводил 0 (ANSI).

Вот смотрите. Открываем файл для записи в ANSI. Пишем латиницу в ANSI. Вызываем FileGetEncoding.
AutoIt анализирует содержимое и определяет, что кодировка подходит и под ANSI и под UTF8. И он выбирает UTF8. До версии 3.3.14 он бы выбрал ANSI.
Код:
$f = FileOpen("ansi.txt", 2 + 512)
FileWrite($f, "abcdef")
FileClose($f)
$Enc = FileGetEncoding("ansi.txt")
ConsoleWrite($Enc & @CRLF)


А вы говорите, что
Хорошо. Перефразирую. Ini-функции AutoIt не работают с utf8, отличной от латиницы. Также, не работают с латиницей с BOM, если первая строка инишника на пустая.
 
Автор
W

winkot

Новичок
Сообщения
188
Репутация
0
Спасибо! С инишниками ясно. Но, что интересно, Notepad может сохранить файл с русскими буквами в UTF8. Вот это не понятно. Как же он это делает, если в UTF8 в принципе нет русских букв?
 

InnI

AutoIT Гуру
Сообщения
4,949
Репутация
1,443
Notepad может сохранить файл с русскими буквами в UTF8
AutoIt тоже может
Код:
$f = FileOpen("bom.txt", 2 + 128)
FileWrite($f, "проверка сохранения кириллицы с bom")
FileClose($f)

$f = FileOpen("nobom.txt", 2 + 256)
FileWrite($f, "проверка сохранения кириллицы без bom")
FileClose($f)

ShellExecute("bom.txt")
ShellExecute("nobom.txt")


в UTF8 в принципе нет русских букв
Открою секрет - там даже китайские "буквы" есть. В этом и смысл юникода.
 

Prog

Продвинутый
Сообщения
585
Репутация
72
Как же он это делает, если в UTF8 в принципе нет русских букв?
Почему вы так решили?
То что в AutoIt, ini функции не читают русский при кодировке utf8, вовсе не значит что эта кодировка не поддерживает русский. Это недостаток функций AutoIt, а не кодировки utf8.
 

AZJIO

Меценат
Меценат
Сообщения
2,891
Репутация
1,195
И это означает, что файл записан в UTF8. А вы говорите, что
Под капотом вызывается функция WritePrivateProfileString(), ей пофиг что сказал AutoIt3.

если в UTF8 в принципе нет русских букв?
ANSI это 256 символов, где символы от 128 до 256 являются национальными и зависят от страны, у каждого свои, поэтому текст в ANSI не могут прочитать в других странах.
UTF8 содержит все языки мира, 65535 символов. Открой таблицу символов charmap.exe и посмотри сколько их там и то не все, зависит от шрифта. Не каждый шрифт может похвастаться набором всех символов. Когда кликаешь на символ снизу будет показан его код, если этот код вставить в функцию ChrW() то он вернёт букву. Русский алфавит от 0x0410 до 0x44F (без ё)

Код:
$sText = ""
For $i = 0x410 To 0x44F
    $sText &= ChrW($i)
Next
; Отображает символы Unicode с их кодами от 0x410 до 0x44F
MsgBox(4096, "Символы Unicode от 0x410 до 0x44F", $sText)
 
Последнее редактирование:
Автор
W

winkot

Новичок
Сообщения
188
Репутация
0
Это недостаток функций AutoIt
Вот теперь понятно. Что-то многовато у AutoIt косяков, мелких, но тем не менее...
В таком случае, наверное, лучше будет настройки хранить в реестре, чем в инишнике?
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
585
Репутация
72
UTF8 содержит все языки мира, 65535 символов.
Это UTF-16.
UTF8 каждый символ кодирует переменным числом байт, от 1 до 4.

winkot, для чего нужно записывать текст в ini в UTF-8? Чем кодировки ASCII и UTF-16 не подошли?
 
Автор
W

winkot

Новичок
Сообщения
188
Репутация
0
Что за косяк-то? Если вы не умеете использовать, причём тут AutoIt3?
Это недостаток функций AutoIt, а не кодировки utf8.
Может быть я и не умею его использовать, но и знающие люди так же отмечают это как недостаток.
 

Prog

Продвинутый
Сообщения
585
Репутация
72
Выше написали почему нельзя использовать utf-8. Это ограничение WinAPI функций ReadPrivateProfileString() и WritePrivateProfileString().
Сохраните файл в кодировке ASCII или UTF-16.
 

AZJIO

Меценат
Меценат
Сообщения
2,891
Репутация
1,195
Это UTF-16.
UTF8 каждый символ кодирует переменным числом байт, от 1 до 4.
UTF8 да больше, но я не поднимал вопрос про ширину символов. Просто если мы используем в Windows переменные в формате UTF16, то по сути мы не можем сохранить UTF8 больше чем подразумевает UTF16.
И я давно уже понял причину использования UTF16: с точки зрения парсинга это постоянная ширина символа, из-за чего при поиске символов синтаксиса происходит сдвиг на 2 байта всегда. В UTF8 такого нет, надо следить за концом символа, чтобы определить его длину, из-за чего это будет работать медленно.
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
585
Репутация
72
UTF8 да больше, но я не поднимал вопрос про ширину символов.
У UTF-8 нет ограничения 65535 символов. Вот и чем я.
UTF-16 тоже нет этого ограничения, т. к. поддерживаются суррогатные пары.
И я давно уже понял причину использования UTF16: с точки зрения парсинга это постоянная ширина символа
Символ может занимать 4 байта в случае суррогатной пары.
 
Верх