Por que o printf relata um erro em todos os Pontos de Codificação Unicode, exceto em três (intervalo ASCII), mas está bem com todos os outros?

2

O 'printf' a que me refiro é o "programa" de edição padrão (não o incorporado): /usr/bin/printf

Eu estava testando o printf como um método viável de converter um Codexoint Hex-literal Unicode em sua representação de caractere Unicoder,

Eu estava com boa aparência e parecia impecável .. (btw. o printf embutido não pode fazer isso (eu acho) ...

Eu então pensei em testá-lo no extremo inferior do espectro de código, e ele falhou com uma avalanche de erros. Tudo na faixa ASCII (= 7 bits)

O mais estranho foi que o valor 3 foi impresso normalmente; eles são:

  • $ \ u0024
  • @ \ u0040
  • '\ u0060

Eu gostaria de saber o que está acontecendo aqui. O conjunto de caracteres ASCII é definitivamente parte da sequência de pontos de código Unicode ....

Eu estou perplexo, e ainda sem uma boa maneira de basear este script em particular. Sugestões são bem vindas.

Para se divertir com a mesma avalanche de erros, cole o seguinte código em um terminal ...

# Here is one of the error messages
# /usr/bin/printf: invalid universal character name \u0041
#  ...for them all, run the following script
( 
for nib1 in {0..9} {A..F}; do 
  for nib0 in {0..9} {A..F}; do
   [[ $nib1 < A ]] && nl="\n" || nl=" "
   $(type -P printf) "\u00$nib1$nib0$nl"
  done
done 
echo 
)
    
por Peter.O 09.01.2011 / 22:19

3 respostas

2

O comando printf tem motivos para não aceitar charters neste intervalo. Se você olhar o código de sounce para printf, você verá este comentário:

A universal character name shall not specify a character short identifier in the range 00000000 through 00000020, 0000007F through 0000009F, or 0000D800 through 0000DFFF inclusive. A universal character name shall not designate a character in the required character set.

Você pode ser capaz de recompilar sem essa verificação, mas parece muito deliberado para mim. Tente usar o comando sem o \ u, por exemplo:

( 
for nib1 in {0..9} {A..F}; do 
  for nib0 in {0..9} {A..F}; do
   $(type -P printf) "
( 
for nib1 in {0..9} {A..F}; do 
  for nib0 in {0..9} {A..F}; do
   $(type -P printf) "%pre%$nib1$nib0"
  done
done 
echo 
)
$nib1$nib0" done done echo )
    
por Martin Owens -doctormo- 10.01.2011 / 03:50
3

Os três caracteres de trabalho são os três caracteres ASCII imprimíveis que não estão no C conjunto de caracteres básicos . A razão pela qual esses caracteres são proibidos em C é que seria difícil para os compiladores: eles precisariam executar a interpolação \u antes da análise lexical, que acho que quebraria em alguns casos, e seria impraticável em muitos compiladores de qualquer forma (porque os caracteres fora do conjunto básico só precisam ser permitidos em alguns lugares).

Ter os mesmos caracteres proibidos não faz sentido em um utilitário de shell. Eu suspeito que isso seja um bug, e $ , @ e ' também não devem funcionar. A razão para não apoiá-los é novamente para facilitar a análise de cadeias de caracteres. Por exemplo, se você quiser determinar que não há caractere especial em uma string que será colocada em uma consulta de banco de dados , pode verificar se a string não contém ' e não se preocupar com isso contendo \u002a .

Considere o uso de recode como sugerido no GNU coreutils manual , ou (mais portátil na prática) Perl ou python.

    
por Gilles 11.01.2011 / 01:06
-1
(for nib1 in {0..9} {A..F}; do 
  for nib0 in {0..9} {A..F}; do
   $(type -P printf) "\x$nib1$nib0"
  done
done 
echo )

impressões (formato manual ajustado)

            


                    
   ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ 
 ' a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �

Observe que alguns códigos de controle de "caracteres" "funcionaram", isto é. HT, VT, LF. etc.

    
por george rowell 13.03.2013 / 15:24