STDIN и Powershell - Как сделать так, чтобы кодировка соответствовала?

У меня проблема с Ruby (1.9.3) и Powershell.

Мне нужно написать интерактивное консольное приложение, которое будет обрабатывать предложения на польском языке. Мне помогли и я могу получить элементы ARGV с польскими диакритическими знаками, но стандартный ввод не работает так, как я хочу.

Иллюстрация кода:

# encoding: UTF-8
target = ARGV[0].dup.force_encoding('CP1250').encode('UTF-8')
puts "string constant = dupą"
puts "dupą".bytes.to_a.to_s
puts "dupą".encoding

puts "target = " +target
puts target.bytes.to_a.to_s
puts target.encoding
puts target.eql? "dupą"

STDIN.set_encoding("CP1250", "UTF-8") 
# the line above changes nothing, it can be removed and the result is still the same
# I obviously wanted to mimic the ARGV solution

target2 = STDIN.gets
puts "target2 = " +target2
puts target2.bytes.to_a.to_s
puts target2.encoding
puts target2.eql? "dupą"

Выход:

string constant = dupą
[100, 117, 112, 196, 133]
UTF-8
target = dupą
[100, 117, 112, 196, 133]
UTF-8
true
dupą //this is fed to STDIN.gets
target2 = dup
[100, 117, 112]
UTF-8
false

Очевидно, Руби никогда не получает четвертого персонажа из STDIN.gets. Если я напишу более длинную строку, как dupąlalalaвсе еще только три начальных байта появляются в программе.

  • Я попытался перечислить байты и зацикливаться на getc, но кажется, что они никогда не достигают Ruby (где они потерялись?)
  • Я использовал chcp 65001 (кажется, ничего не меняет)
  • Я изменил свой $OutputEncoding на [Console]::OutputEncoding; теперь это выглядит так:

     IsSingleByte      : True
     BodyName          : ibm852
     EncodingName      : Środkowoeuropejski (DOS)
     HeaderName        : ibm852 
     WebName           : ibm852
     WindowsCodePage   : 1250
     IsBrowserDisplay  : True
     IsBrowserSave     : True
     IsMailNewsDisplay : False
     IsMailNewsSave    : False
     EncoderFallback   : System.Text.InternalEncoderBestFitFallback
     DecoderFallback   : System.Text.InternalDecoderBestFitFallback
     IsReadOnly        : True
     CodePage          : 852
    
  • Я использую шрифт Consolas

Что мне делать, чтобы правильно читать польские диакритические знаки в Powershell?

2 ответа

Я узнал некоторую соответствующую информацию. Не уверен, что это именно правильная информация. Но, эй, у ОП уже есть другое решение.

# Get "encoding" for code page 1250 (Central European)
$en=[System.Text.Encoding]::GetEncoding(1250)
# Looks like this:
IsSingleByte      : True
BodyName          : iso-8859-2
EncodingName      : Central European (Windows)
HeaderName        : windows-1250
WebName           : windows-1250
WindowsCodePage   : 1250
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : True
CodePage          : 1250

# Change STDIN's input encoding
[console]::InputEncoding=$en
$x = Read-Host 
# I typed in dupą 
#  (I set Polish in Languate Bar. 
#   Final letter is apostrophe on US English keyboard)
[int[]][char[]]$x
# output is: 100 117 112 261 (in hex): 64 75 70 105
# the final character (261) is "Latin Small Letter A with Ogonek" 

.Net 4.x ожидает и создает метку порядка байтов (BOM) с CHCP 65001 (UTF-8) на стандартном вводе.

Кажется, это исправлено в .Net Core, но требует изменения Console.StandardInputEncodingв 4.x, чтобы правильно перехватывать связь с дочерними процессами, у которых нет подобных предположений.

Другие вопросы по тегам