Introdução de valores ascii estendidos

0

Ei, estou perdendo a cabeça por isso, eu tenho um programa escrito em c que obtém alguma string como uma entrada diretamente do terminal e imprime o valor ascii de cada byte digitado dentro da string, Estou tentando inserir valores ascii estendidos (o valor é maior que 127) e não estou conseguindo fazer isso. especificamente eu preciso inserir o valor ascii de 137 como uma entrada para a string - > daí entra um personagem com esse valor eu tentei quase tudo:

  • Compor chave e inserir: e + "
  • Valor Unicode ctrl + shift + u seguido pelo valor hexadecimal do código ascii - Insere-o como unicode, portanto, leva dois bytes em vez de um byte wth o valor de 137
  • ctrl + d - não suporta valores ascii estendidos

de qualquer forma, se alguém souber como resolver isso, seria útil para mim

    
por DrPrItay 17.01.2017 / 13:56

3 respostas

2

Você poderia usar o luit , que permitiria que você executasse seu aplicativo cp850 (o que for locale você pode encontrar para isso) em um terminal UTF-8, e deixe luit fazer a tradução de / para o UTF-8.

Por que vale a pena, uma captura de tela do cp850 com o luit:

As capturas de tela foram configuradas por um conjunto de scripts que exibiram uma tela de teste para cada codificação de localidade. Nem todas as codificações têm informações de localidade correspondentes configuradas. As 761 locales listadas no meu sistema Debian 7 usando locale -a correspondem a apenas 32 codificações:

  ANSI_X3.4-1968      EUC-TW              ISO-8859-14         ISO-8859-9
  ARMSCII-8           GB18030             ISO-8859-15         KOI8-R
  BIG5                GB2312              ISO-8859-2          KOI8-T
  BIG5-HKSCS          GBK                 ISO-8859-3          KOI8-U
  CP1251              GEORGIAN-PS         ISO-8859-5          RK1048
  CP1255              ISO-8859-1          ISO-8859-6          TCVN5712-1
  EUC-JP              ISO-8859-10         ISO-8859-7          TIS-620
  EUC-KR              ISO-8859-13         ISO-8859-8          UTF-8

Se você tiver uma versão recente (por exemplo, 2.0 em 2013) do luit e as informações de localidade instaladas, a execução é simples:

luit -encoding cp850

Isso executa um shell no qual os aplicativos usam a página de códigos 850, mas seu select / paste (e teclado) são traduzidos para / da codificação de localidade no shell externo (assumido como sendo UTF-8, pois não funcionaria com apenas a localidade POSIX).

A opção -v (verbose) mostra um pequeno detalhe:

$ luit -encoding cp850 -v -v
getCharsetByName(ASCII)
cachedCharset 'ASCII'
getCharsetByName(<null>)
using unknown 94-charset
getCharsetByName(CP 850)
cachedCharset 'CP 850'
getCharsetByName(<null>)
using unknown 94-charset
Input: G0 is ASCII, G1 is Unknown (94), G2 is CP 850, G3 is Unknown (94).
GL is G0, GR is G2.
Output: G0 is ASCII, G1 is Unknown (94), G2 is CP 850, G3 is Unknown (94).
GL is G0, GR is G2.

O uso do antigo luit não funciona tão bem, pois depende de informações incompletas do local. Veja o que a luit 1.1.1 faz:

$ luit -encoding cp850 -v -v
Warning: couldn't find charset data for locale cp850; using ISO 8859-1.
G0 is ASCII, G1 is Unknown (94), G2 is ISO 8859-1, G3 is Unknown (94).
GL is G0, GR is G2.

Se você estiver executando o OpenSuSE, isso fornece um pacote. No outro extremo (por exemplo, Ubuntu), configurar as localidades é um incômodo, mas compilar luit da fonte é relativamente simples.

    
por 17.01.2017 / 22:19
1

Bytes não são caracteres e caracteres não são bytes. A correspondência entre caracteres e bytes depende da localidade. Em uma localidade UTF-8, o caractere &#137; seria representado por dois bytes, \xC2\x89 (194 e 137 em decimal); um byte vazio com o valor \x89 (137 decimal) seria inválido. Como inserir caracteres que não aparecem no teclado depende do terminal e do ambiente de trabalho.

Se tudo que você quer é enviar bytes arbitrários para um programa, você pode usar um pipe, por exemplo:

$ echo -ne '\x89' | hexdump -C
00000000  89                                                |.|
00000001
    
por 17.01.2017 / 17:10
0

ASCII é uma codificação de caracteres de 7 bits. Faz uma correspondência entre valores inteiros no intervalo de 0 a 127, e um monte de caracteres (nem todos imprimíveis). Este intervalo não inclui 137: não existe um valor “ascii de 137”.

Parece que você deseja inserir o byte cujo valor numérico é 137 e o programa imprime esse valor numérico em hexadecimal. Isso não tem nada a ver com o ASCII, mas tem a ver com a codificação usada no terminal. Para inserir o byte 137, você precisa inserir um caractere que seja codificado por esse byte. Os sistemas modernos usam UTF-8 , onde a maioria dos caracteres é codificada por múltiplos bytes. Não há nenhum caractere cuja codificação UTF-8 seja a sequência de bytes {137}, ou mesmo qualquer caractere cuja codificação comece com esse valor de byte (todas as codificações multibyte começam com um valor acima de 192). Há caracteres cuja codificação é uma sequência de dois bytes, em que o segundo byte é 137, no entanto, como É = U + 00C9, codificado em UTF-8 como {195, 137}.

Se você quiser enviar valores de byte arbitrários digitando-os, será necessário usar uma codificação unibyte. Escolha um que não tenha caracteres não imprimíveis (por exemplo, o intervalo de 128 a 159 não pode ser imprimido na codificação latina-1), como cp850. Veja a resposta de Thomas Dickey sobre como usar o luit para isso.

Como alternativa, você pode inserir um valor de byte arbitrário fazendo com que o programa leia a partir de um arquivo que os contenha ou canalizando-os de um programa que os produz. Por exemplo, no bash, você pode escrever

printf \211 | ./myprogram            # works in any shell
printf $'\x89' | ./myprogram
./myprogram <<<$'\x89'
    
por 18.01.2017 / 02:02