在字符串文字中使用哪些字符是合法的?
What characters are legal to use in string literals?
我想知道在 C 语言中 按字面意思 放置 ascii
个字符是否合法,例如 TAB
、BEL
和 ESC
直接在字符串文字中。
在 Whosebug 上无法以纯文本显示字符,所以我不得不截屏。
没有图形表示的字符使用 Caret notation 显示,并在屏幕截图中以紫色突出显示。在第 7
行还有一个 TAB
字符用于缩进文本。
使用 gcc -std=c99 -pedantic
编译时没有任何警告,但它真的完全可移植吗?
我不会将其用于任何严肃的程序。我只是好奇标准是否允许它。
一个以 null 结尾的字符串只是一些 8 位值,根据它们的符号可以是 0-255 或 -128-127。
当您将字节发送到终端之类的东西时,如何处理字节完全取决于终端。像 'a'-'z' 这样的一些字节可能是标准的,但前提是您假设 8 位字符编码。其他字节,如“€”,可能只有使用正确的字符集才能正确显示。
最后我们有了那些终端控制字节来控制光标和响铃。处理这些字节完全取决于终端,但写入它们仍然是有效的 C 代码。
程序源中可移植的字符就是这些:
拉丁字母的26个大写字母
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
26个小写拉丁字母
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
十进制数
0 1 2 3 4 5 6 7 8 9
以下29个图形字符
! " # % & ' ( ) * + , - . / :
; < = > ? [ \ ] ^ _ { | } ~
- space 字符,以及表示水平制表符、垂直制表符和换页符的控制字符。
来源:C 标准,任何版本。
实现必须接受这些字符,并且允许接受任何其他字符。
如果反斜杠紧跟文字换行符(不是 \n
),则反斜杠和换行符都会被删除。除了三字母组之间的任何地方都可以像这样拆分行(如果三字母组被反斜杠换行序列拆分,则该序列被删除,但三字母组保持不变)。
字符串文字(在可移植代码中)允许使用文字制表符,并且与 \t
具有相同的语义。 C11 (n1570) 6.4.5 p1 指出,"any member of the source character set except the double-quote "
, backslash \
, or new-line character" 可以是字符串文字的一部分,制表符是源字符集的一部分(同上。5.2.1 p3)。
转义字符 (\e
, ASCII 0x1b) 不是源字符集的一部分,甚至可能根本不存在(在非 ASCII 系统上)。同样适用于换页,尽管 \f
是 C 标准的一部分。这些字符不能移植使用。
一个实现可以自由接受它喜欢的任何字符(除了标准的最低要求),从源字符集到执行字符集的映射是实现定义的(一个实现可以映射不同的字符源代码为相等的字符)。
我想知道在 C 语言中 按字面意思 放置 ascii
个字符是否合法,例如 TAB
、BEL
和 ESC
直接在字符串文字中。
在 Whosebug 上无法以纯文本显示字符,所以我不得不截屏。
没有图形表示的字符使用 Caret notation 显示,并在屏幕截图中以紫色突出显示。在第 7
行还有一个 TAB
字符用于缩进文本。
使用 gcc -std=c99 -pedantic
编译时没有任何警告,但它真的完全可移植吗?
我不会将其用于任何严肃的程序。我只是好奇标准是否允许它。
一个以 null 结尾的字符串只是一些 8 位值,根据它们的符号可以是 0-255 或 -128-127。
当您将字节发送到终端之类的东西时,如何处理字节完全取决于终端。像 'a'-'z' 这样的一些字节可能是标准的,但前提是您假设 8 位字符编码。其他字节,如“€”,可能只有使用正确的字符集才能正确显示。
最后我们有了那些终端控制字节来控制光标和响铃。处理这些字节完全取决于终端,但写入它们仍然是有效的 C 代码。
程序源中可移植的字符就是这些:
拉丁字母的26个大写字母
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
26个小写拉丁字母
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
十进制数
0 1 2 3 4 5 6 7 8 9
以下29个图形字符
! " # % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~
- space 字符,以及表示水平制表符、垂直制表符和换页符的控制字符。
来源:C 标准,任何版本。
实现必须接受这些字符,并且允许接受任何其他字符。
如果反斜杠紧跟文字换行符(不是 \n
),则反斜杠和换行符都会被删除。除了三字母组之间的任何地方都可以像这样拆分行(如果三字母组被反斜杠换行序列拆分,则该序列被删除,但三字母组保持不变)。
字符串文字(在可移植代码中)允许使用文字制表符,并且与 \t
具有相同的语义。 C11 (n1570) 6.4.5 p1 指出,"any member of the source character set except the double-quote "
, backslash \
, or new-line character" 可以是字符串文字的一部分,制表符是源字符集的一部分(同上。5.2.1 p3)。
转义字符 (\e
, ASCII 0x1b) 不是源字符集的一部分,甚至可能根本不存在(在非 ASCII 系统上)。同样适用于换页,尽管 \f
是 C 标准的一部分。这些字符不能移植使用。
一个实现可以自由接受它喜欢的任何字符(除了标准的最低要求),从源字符集到执行字符集的映射是实现定义的(一个实现可以映射不同的字符源代码为相等的字符)。