Замечания и предложения

У меня не установлена XP, так что это - угадайка

Меня больше Linux волнует - в нем непредсказуемо происходит какая то ошибка с изменением файла извне. Я бы пока потестил Linux без потоков - может, там и не в потоках дело.

Не исправляйте как “пример исправлений” - мы либо принимаем всё, либо не принимаем. Разбираться в чужом коде, переключаться на него - так себе деятельность

Мда, это всё конечно грустно. @spectatorBH я так понимаю вам релевантно - можете тогда вы протестить?

Я скоро тоже тестить всё буду, для моих модулей понадобится. А пока я мелочи дочищал, чтобы в линуксе об них не вспотыкаться.

Та и не надо в том коде сильно копаться. Смысл был в том чтобы было видно в какой части проблема. Может лучше было сделать в виде драфта, чтобы его и нельзя было так просто принять?

Ну да ладно, пусть тогда пока живёт в виде issue. А я сам буду использовать свои же исправления.

## var s := ReadString;
$'{s.Length}: [{s}]'.Print;
s.Select(ch->ch.Code).Print;
Readln;

В окне ввода всё нормально работает, но если запускаю с Shift+F9 и ввожу русские буквы - строку s заполняет нулевыми символами.

Вроде всё верно

А Readln зачем в конце? У кого-то консоль сама закрывается?

Возможно потому что винда вся на англ? Но вроде раньше и у меня русский ввод работал.

Для этого пунк в настройках есть. Я выключил, потому что не всегда удобно.

Это странно - Unicode он и в африке Unicode

Похоже что нет:

## uses System.Text;
Writeln(Console.InputEncoding);
Console.InputEncoding := Encoding.Unicode;
Writeln(Console.InputEncoding);

// А это неважно
//Console.OutputEncoding := Encoding.Unicode;

var s := ReadString;
$'{s.Length}: [{s}]'.Print;
s.Select(ch->ch.Code).Print;
Readln;

По-умолчанию в Console.InputEncoding стоит UTF-8. Если я меняю на UTF-16 - русские символы начинают работать.

Без смены кодировки:

Со сменой кодировки:


+ почему то цвет вывода меняется на крассный:

P.S. Из за этого символа:

##
'Вывод чёрным'#65533.Println;
'Вывод красным'.Println;

Так и есть. Это у нас секретные символы цветов

1 лайк

А, вижу, 65531..65535 (char(-5..-1)). Так а где это используется?

И что всё же с кодировками, а то у меня только англ. версии винды под рукой…

P.S. А нет, одна всё же русская, и результаты на всех разные.

На второй англ. винде кодировка по умолчанию IBM437 и там русские символы превращаются в вопросы (символы #63).
Строчка Console.InputEncoding := Encoding.Unicode так же всё исправляет.

А русская винда имеет доисторическую версию (так что от win8 отличить сложно) и отказывается обновляться. Там по умолчанию на вводе cp866.
При установки UTF-16 на вывод консоль крашится (сообщение на экране тоже зажовывает между кодировками, поэтому ничего кроме чисел прочитать нельзя). Но у меня получилось выводить русские символы, после того как я установил cp866 и в Console.OutputEncoding (вместо UTF-8). Но тогда украинские символы становятся вопросами.
Тем не менее, опять же, после установки Console.InputEncoding := Encoding.Unicode - по крайней мере коды символов в string стали правильные, и для англ., и для русских, и для украинских символов. С выводом в cp866 тоже работает (но, опять же, не для укр. символов).

И до ещё 1 русской винды добрался. У неё тоже кодировки cp866 (ввод) и UTF-8 (вывод). На ней, по крайней мере, работают русские и англ. символы без доп. танцев с бубном.

Установка UTF-16 на ввод делает так что любые символы, хоть японские, правильно читаются в string (то есть коды символов правильные).
Но выводить всё кроме англ. и русских символов всё равно отказывается, даже при выводе UTF-16.

Как раз для колоризованного вывода в оболочке

Честно говоря, я поражен. Потому что я считал, что Utf-8 выводит символы всех алфавитов мира. И Utf-16 здесь не имеет преимуществ.

У нас в PABCSystem прописано if (System.Environment.OSVersion.Version.Major >= 6) and (System.Environment.OSVersion.Version.Minor >= 2) then System.Console.OutputEncoding := Encoding.UTF8;

Это как раз для современных версий винды

Ну так это кодировка вывода. Там уже дальше зависит от шрифта консоли - если в нём нет символа - его всё равно не выведет.

А я тут говорю про Console.InputEncoding - то есть кодировку ввода. И на большинстве компов в этом свойстве был вообще не юникод.

С UTF-8 на вводе (который на моём компе по-умолчанию) - тоже не понимаю почему не работает. Но предполагаю что дело в переводах между кодировками. Или может консоль считает её однобайтовой кодировкой? Ну, самое странное что у меня последняя версия win10. Я так понимаю у вас тоже. То есть дело должно быть в настройках?

Но, string всё же хранится именно в UTF-16. Поэтому перевод в/из UTF-8 для консоли, в любом случае не сдался. Экономия памяти там не на том маштабе, чтобы было заметно. А совместимость с 127 символами ASCII, на экране консоли, вообще ничего не делает.

Если настройки то есть подозрение на эту:

image

Она по умолчанию выключена. Но было бы странно если бы её включение ломало UTF-8 - вроде я её включил как раз чтобы исправить что то с ним связанное.

Протестить сейчас не могу, потому что оно просит перезагрузку, а мне слишком много всего заново открывать придётся.

Понятно, опять игнор… Тем временем я попробовал сделать #2726.

И простенькие программки прекрасно работают. Но проблема при интерапе с не_паскальными программами.
К примеру упаковщики POCGL запускают процессы гита с простыми командами, чтобы скачать XML данные об исходных .dll . Но если Console.InputEncoding переключён на UTF16 - вывод гита тоже пытается прочитать как UTF16, хотя он по умолчанию UTF8.
Это, конечно, не годится…

И в любом случае, стоит всё же разобраться почему у меня с UTF8 всё так криво. Но пока все зацепки что нагуглил - были бесполезны.

Должно ли быть так, и почему это происходит? При упоминании в коде программы символ * число IsConsoleApplication переключается на true вне зависимости от того, запущена ли программа из-под оболочки или без связи с оболочкой. Примеры:

##
Write(IsConsoleApplication); //True
if false then
  Write(' ' * 0);
##
Write(IsConsoleApplication); //True
if false then
begin
  var str := '1' * 2;
end;
##
Write(IsConsoleApplication); //False
if false then
begin
  var str := '12' * 2; //Теперь на число умножается не символ, а строка
end;

Не могу воспроизвести, у меня во всех случаях, и при запуске с F9, и с Shift+F9 - выводит True.

Я считаю, что

должно быть false, так как эта переменная как раз используется для определения запуска из-под оболочки: