Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Free Pascal, Pascal ABC и другие _ Что с кодировкой?

Автор: camac 20.06.2019 2:46

Удалась возможность разжиться ПК с Виндовс.
И столкнулся с непонятным. Кодировка СР1251. В консоли выбран шрифт Lucida Console, т. е. той же кодировки. Текст отображается правильно. Но тот текст, который я ввожу - крякозябрами. Т. е. в DOS'овской кодировке? СР866?
Изображение

Автор: camac 20.06.2019 16:00

Самое смешное - в Линуксе у консоли в настройках указал кодировку СР1251. И все нормально. Никаких иероглифов.

Автор: camac 21.06.2019 0:22

Итак, решение:
1) подключаем модуль windows

Код

     uses windows;

2) в начале главной программы пишем
Код

     SetConsoleCP(1251);
     SetConsoleOutputCP(1251);

Спасибо всем "за помощь"
Тему можно закрывать.

Автор: OCTAGRAM 23.06.2019 4:47

Какая версия FPC? Это 3.0 себя так ведёт? Он же вроде Юникодный, там должны были попрощаться наконец с бредом про кодировки

WriteConsoleW в Windows, во всяком случае, работает в Юникоде, и лучше пользоваться WinAPI, если в FPC RTL такая древняя, что до сих пор остались какие-то кодировки.

Более правильно было бы не конкретно CP1251, а, наверное, CP_ACP. Это раз. Не знаю, как там с файловой системой работа, но если консольное API для древних, работающих в однобайтных кодировках, программ, переключено в ANSI, то файловое API для древних, работающих в однобайтных кодировках, программ, по-прежнему работает в OEM, и это может быть проблемой. Тогда ещё SetFileApisToAnsi может потребоваться.

Но вообще просто не надо в 2019 писать с кодировками, отличными от кодировок Юникода

Автор: camac 24.06.2019 13:49

Цитата(OCTAGRAM @ 23.06.2019 0:47) *

не надо в 2019 писать с кодировками, отличными от кодировок Юникода

Виндовая консоль "понимает" кодировки только СР866 и СР1251. FPC - 3.0

Автор: OCTAGRAM 24.06.2019 15:32

В виндовую консоль надо писать WriteConsoleW, который принципиально UCS2. Тут, правда, с виндовой консолью свои заморочки. Ведь вывод команды может захотеться перенаправить в файл или трубу, а в файл или трубу нельзя сделать WriteConsoleW. Значит, надо на старте понять, чем являются перенаправленные каналы Input, Output, ErrOutput, и в зависимости от этого писать в них через WriteConsoleW или через WriteFile.

Вот если через WriteFile работать с консолью, тогда да, тут возникают кодировки. Тоже тут не обходится без шаманства, но http://archives.miloush.net/michkap/archive/2010/10/07/10072032.html и какой современный node.js ни возьми, никакую «кодировку» из него в консоль не выдавишь. JavaScript в node.js оперирует UTF-16, и этот UTF-16 так и идёт в консоль.

Адский транслятор GNAT базируется на GCC, а в GCC для совместимости с POSIX потоки 8битные, однако там сделана прослойка, которая обнаруживает наличие консоли Windows, и при обнаружении консоли перекодирует из UTF-8 в UTF-16 и пишет с использованием WriteConsoleW. Везде в современных библиотеках времени исполнения эту дыру, чтоб запись в консоль Windows могла провалиться во WriteFile, позакрывали. Везде поставили это нехитрое шаманство. А у FPC за 9 лет, похоже, таких рабочих рук не нашлось, и он остался в каменном веке. Пишет через WriteFile. Впрочем, я сейчас посмотрел, как в Delphi Tokyo на работе, и там тоже это убожество с кодировками вместо WriteConsoleW. System.Write юникодный, но затем он перекодирует в однобайтовую системную кодировку.

В общем, кодировкам, отличным от кодировок Юникода, решительный бой. А если эти кодировки прямо в сердце, в стандартной библиотеке, то такой стандартной библиотеке решительный бой. И даже шаманства особого не потребуется. Шаманство нужно, если не понятно, перенаправлен вывод или нет. Рисовать диалоги в выводе, перенаправленном в файл или трубу — занятие бессмысленное, так что прописывать отдельно вывод в файл и консоль, и различение между ними, бессмысленно. Только консоль, только консольное WinAPI, а оно довольно простое.