为什么 printf 除了三个(ASCII 范围)Unicode 代码点外,其他代码点都会报告错误,而其他代码点却没问题?

为什么 printf 除了三个(ASCII 范围)Unicode 代码点外,其他代码点都会报告错误,而其他代码点却没问题?

我提到的“printf”是标准“程序”(不是内置的):/usr/bin/printf

我正在测试 printf out 作为一种可行的方法,将 Unicode Codepoint Hex 文字转换为其 Unicoder 字符表示形式,

我看起来很好,似乎完美无缺......(顺便说一句,内置的 printf 根本不能做到这一点(我认为)......

然后我想在代码频谱的最低端进行测试,但结果失败了,出现了大量错误。所有错误都在 ASCII 范围内(= 7 位)

最奇怪的是,3个值正常打印;它们是:

  • $ \u0024
  • @ \u0040
  • ` \u0060

我想知道这里发生了什么。 ASCII 字符集绝对是 Unicode 码点序列的一部分……

我很困惑,仍然没有一个好的方法来编写这个特殊的转换脚本。欢迎提出建议。

要解决同样的大量错误,请将以下代码粘贴到终端...

# 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 
)

答案1

三个工作字符是三个可打印的 ASCII 字符,它们不在C基本字符集。在 C 中禁止使用这些字符的原因是,这会给编译器带来困难:它们需要\u在词法分析之前执行插值,我认为这会在某些极端情况下出现问题,而且在许多编译器中也不切实际(因为基本字符集之外的字符只需要在少数地方允许使用)。

在 shell 实用程序中,使用相同的禁用字符是没有意义的。我怀疑这是一个错误,并且$@并且`应该起作用。不支持它们的原因再次是为了使解析字符串变得更容易。例如,如果你想确定没有要在数据库查询中输入的字符串中的特殊字符,您可以检查字符串不包含',而不必担心它包含\u002a

考虑使用重新编码就像GNU coreutils 手册,或者(实际上更具可移植性)Perl 或 python。

答案2

printf 命令不接受此范围内的字符是有原因的。如果您查看 printf 的源代码,您将看到以下注释:

通用字符名称不得指定 00000000 至 00000020、0000007F 至 0000009F 或 0000D800 至 0000DFFF(含)范围内的字符短标识符。通用字符名称不得指定所需字符集中的字符。

可能无需进行该检查即可重新编译,但我认为这是非常刻意的。尝试使用不带 \u 的命令,例如:

( 
for nib1 in {0..9} {A..F}; do 
  for nib0 in {0..9} {A..F}; do
   $(type -P printf) "\00$nib1$nib0"
  done
done 
echo 
)

答案3

(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 )

打印件(手工调整格式)

            


                    
   ! " # $ % & ' ( ) * + , - . / 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 { | } ~  
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
 � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �

请注意,一些“字符”控制代码“起作用”,即 HT、VT、LF 等。

相关内容