为什么 C 不能识别跨多行的字符串?
Why does C not recognize strings across multiple lines?
(我对C还很陌生)
视觉换行符在 C 中似乎并不重要。
例如:
int i; int j;
与
相同
int i;
int j;
和
int k = 0 ;
与
相同
int
k
=
0
;
那为什么是
"hello
hello"
与
不一样
"hello hello"
字符串可以通过在换行符前加一个反斜杠来在换行符上继续:
"hello \
hello"
或者(更好),使用字符串连接:
"hello "
"hello"
请注意,space 已被仔细保留,因此这些等同于 "hello hello"
,除了文件中出现后的行号。
backslash-newline 行消除在翻译过程的早期完成 — 在概念 translation phases 的第 2 阶段。
请注意,没有剥离前导空格或任何内容。如果你写:
printf("Some long string with maybe an integer %d in it\
and some more data on the next line\n", i);
然后字符串在 in it
和 and some
之间有一个(至少)8 个空格的序列。计数 8 假定 printf()
语句在左边距对齐;如果它是缩进的,你需要添加额外的白色 space 对应于缩进。
这是因为包含起始引号字符而不是结束引号字符的行更可能是打字错误或其他错误,而不是尝试跨多行编写字符串,因此决定字符串文字不会跨越源代码行,除非在行尾故意用 \
表示。
此外,当发生此类错误时,编译器将面临读取可能数千行的代码,然后才能确定没有结束引号字符(已到达文件末尾)或找到预期作为开始引号的内容一些其他字符串文字的字符,然后尝试将该字符串文字的内容解析为 C 代码。除了用有限的计算资源给早期编译器增加负担之外,这可能会导致源代码中远离缺失引号字符的部分出现令人困惑的错误消息。
这个选择在C 2018 6.4.5 1中生效,它说一个字符串文字是"
s-char-sequenceopt "
,其中 s-char-sequence 是除引号字符、反斜杠或 new-line 字符之外的字符集的任何成员(并且字符串文字也可能有编码前缀,在第一个 "
之前的 u8
、u
、U
或 L
)。
1- 对每个字符串使用双引号:
char *str = "hello "
"hello" ;
** 这种方法的一个问题是我们需要对引号 " 本身等特殊字符进行转义。
2- 使用 - \ :
char *str = "hello \
hello" ;
** 这种形式写起来容易很多,我们不需要每行都写引号。
We can think of a C program as a series of tokens: groups of characters that can't be split up without changing their meaning. Identifiers and keywords are tokens. So are operators like + and -, punctuation marks such as the comma
and semicolon, and string literals.
例如,行
int i; int j;
由 6 个标记组成:int, i, ;, int、j 和 ;。大多数时候,尤其是在这种情况下,space(space、制表符和换行符)的数量并不重要。这就是为什么编译器会对待
int i
;int
j;
一样。
写作
"Hello
Hello"
就像写作
un signed
并希望编译器将其视为
unsigned
就像关键字之间不允许使用 space 一样,字符串文字标记中也不允许使用换行符。但可以在需要时使用换行转义 '\n' 将其包含在内。
要跨行写入字符串,请使用字符串连接方法
"Hello"
"Hello"
虽然推荐使用上述方法,但您也可以使用反斜杠
"Hello \
Hello"
使用反斜杠的方法,注意换行的开头space。该字符串将包含该行中的所有内容,直到找到结束引号或另一个反斜杠。
(我对C还很陌生)
视觉换行符在 C 中似乎并不重要。 例如:
int i; int j;
与
相同int i;
int j;
和
int k = 0 ;
与
相同int
k
=
0
;
那为什么是
"hello
hello"
与
不一样"hello hello"
字符串可以通过在换行符前加一个反斜杠来在换行符上继续:
"hello \
hello"
或者(更好),使用字符串连接:
"hello "
"hello"
请注意,space 已被仔细保留,因此这些等同于 "hello hello"
,除了文件中出现后的行号。
backslash-newline 行消除在翻译过程的早期完成 — 在概念 translation phases 的第 2 阶段。
请注意,没有剥离前导空格或任何内容。如果你写:
printf("Some long string with maybe an integer %d in it\
and some more data on the next line\n", i);
然后字符串在 in it
和 and some
之间有一个(至少)8 个空格的序列。计数 8 假定 printf()
语句在左边距对齐;如果它是缩进的,你需要添加额外的白色 space 对应于缩进。
这是因为包含起始引号字符而不是结束引号字符的行更可能是打字错误或其他错误,而不是尝试跨多行编写字符串,因此决定字符串文字不会跨越源代码行,除非在行尾故意用 \
表示。
此外,当发生此类错误时,编译器将面临读取可能数千行的代码,然后才能确定没有结束引号字符(已到达文件末尾)或找到预期作为开始引号的内容一些其他字符串文字的字符,然后尝试将该字符串文字的内容解析为 C 代码。除了用有限的计算资源给早期编译器增加负担之外,这可能会导致源代码中远离缺失引号字符的部分出现令人困惑的错误消息。
这个选择在C 2018 6.4.5 1中生效,它说一个字符串文字是"
s-char-sequenceopt "
,其中 s-char-sequence 是除引号字符、反斜杠或 new-line 字符之外的字符集的任何成员(并且字符串文字也可能有编码前缀,在第一个 "
之前的 u8
、u
、U
或 L
)。
1- 对每个字符串使用双引号:
char *str = "hello "
"hello" ;
** 这种方法的一个问题是我们需要对引号 " 本身等特殊字符进行转义。
2- 使用 - \ :
char *str = "hello \
hello" ;
** 这种形式写起来容易很多,我们不需要每行都写引号。
We can think of a C program as a series of tokens: groups of characters that can't be split up without changing their meaning. Identifiers and keywords are tokens. So are operators like + and -, punctuation marks such as the comma and semicolon, and string literals.
例如,行
int i; int j;
由 6 个标记组成:int, i, ;, int、j 和 ;。大多数时候,尤其是在这种情况下,space(space、制表符和换行符)的数量并不重要。这就是为什么编译器会对待
int i
;int
j;
一样。
写作
"Hello
Hello"
就像写作
un signed
并希望编译器将其视为
unsigned
就像关键字之间不允许使用 space 一样,字符串文字标记中也不允许使用换行符。但可以在需要时使用换行转义 '\n' 将其包含在内。
要跨行写入字符串,请使用字符串连接方法
"Hello"
"Hello"
虽然推荐使用上述方法,但您也可以使用反斜杠
"Hello \
Hello"
使用反斜杠的方法,注意换行的开头space。该字符串将包含该行中的所有内容,直到找到结束引号或另一个反斜杠。