创建C字符串解析器
在C(和类似的语言)中,字符串被声明为例如创建C字符串解析器,c,C,在C(和类似的语言)中,字符串被声明为例如“abc”。另一个例子是“ab\“c”。我有一个包含这些字符串的文件。也就是说,文件内容是“abc”或“ab\c”等。可以在.c文件中定义的任何文本字符串都可以在我正在读取的文件中定义 这些字符串的格式可能不正确。例如,“abc(无结束引号)。编写解析器以确保文件中的字符串是有效的C文本字符串的最佳方法是什么?(因此,如果我复制文件内容并将其粘贴到char*str=之后,编译器将在函数顶部接受生成的表达式) 字符串分别位于单独的行中 或者,您可以认为这是
“abc”
。另一个例子是“ab\“c”
。我有一个包含这些字符串的文件。也就是说,文件内容是“abc”
或“ab\c”
等。可以在.c文件中定义的任何文本字符串都可以在我正在读取的文件中定义
这些字符串的格式可能不正确。例如,“abc
(无结束引号)。编写解析器以确保文件中的字符串是有效的C文本字符串的最佳方法是什么?(因此,如果我复制文件内容并将其粘贴到char*str=
之后,编译器将在函数顶部接受生成的表达式)
字符串分别位于单独的行中
或者,您可以认为这是想要解析声明文字字符串变量的行。想象一下,我正在放大一个大文件,并使用
char\*.*=(*)$
并希望确保括号中的部分不会导致编译错误 C字符串文字的语法在C 2018 6.4.5中给出。假设您只想解析普通字符串,而不是那些带有编码前缀的字符串,例如u“xyz”
,那么字符串文本的语法是“
s-char-sequenceopt”
,其中“opt”表示可选,s-char-sequence是一个或多个s-char标记。s字符是源字符集的任何成员,但“
、\
或新行字符除外,或者是转义序列
源字符集至少包括大写和小写的拉丁字母(26个字母A-Z)、十位数字、空格、水平制表符、垂直制表符、换页符,以及以下字符:
"#%&’()*+,-./:;?[\]^_{|}~
"#%&’()*+,-./:;?[\]^_{|}~
但是,C实现可能在其源字符集中包含其他字符。因此,字符串中除“
、\
或新行字符以外的任何字符在某些C实现中都必须被视为潜在有效字符
6.4.4.4.1中定义的逃生顺序为:
后接\
,
,
,
,?
,\
,a
,b
,f
,n
,r
,t
v
后跟一到三个八进制数字,或\
后跟一个或多个十六进制数字,或\x
- 通用字符名
\u
后跟四个十六进制数字或\u
后跟八个十六进制数字。第2款限制了这些:
通用字符名不得指定短标识符小于0024($)、0040(@)或0060(')以外的00A0的字符,也不得指定范围为D800到DFFF(含)的字符
C语法的这一部分看起来很容易解析:
- 字符串文字必须以
开头“
- 如果下一个字符不是
、“
或新行字符,则接受它\
- 如果下一个字符是
,并且后跟上面列出的单个字符之一,请接受它和下面的字符\
- 如果下一个字符是
,后跟一到三个八进制数字,则接受它,最多接受三个八进制数字\
- 如果接下来的两个字符是
,后面跟一个十六进制数字,请接受它们和后面的所有十六进制数字\x
- 如果接下来的两个字符是
,后跟四个十六进制数字,则接受这六个字符。但是,如果该值是上述约束中禁止的值之一,则这不是有效的C字符串文字\u
- 如果接下来的两个字符是
,后跟八个十六进制数字,则接受这十个字符。但是,如果该值是上述约束中禁止的值之一,则这不是有效的C字符串文字\U
- 重复上述操作,直到不接受下一个字符
- 如果下一个字符不是
,则这不是有效的C字符串文字“
- 如果下一个字符是
,请接受它“
- 如果这是从文件中读取的行的结尾,则它是有效的C字符串文字。否则,情况并非如此
u“xyz”
,那么字符串文本的语法是“
s-char-sequenceopt”
,其中“opt”表示可选,s-char-sequence是一个或多个s-char标记。s字符是源字符集的任何成员,但“
、\
或新行字符除外,或者是转义序列
源字符集至少包括大写和小写的拉丁字母(26个字母A-Z)、十位数字、空格、水平制表符、垂直制表符、换页符,以及以下字符:
"#%&’()*+,-./:;?[\]^_{|}~
"#%&’()*+,-./:;?[\]^_{|}~
但是,C实现可能在其源字符集中包含其他字符。因此,字符串中除“
、\
或新行字符以外的任何字符在某些C实现中都必须被视为潜在有效字符
6.4.4.4.1中定义的逃生顺序为:
后接\
,
,
,
,?
,\
,a
,b
,f
,n
,r
,t
v
后跟一到三个八进制数字,或\
后跟一个或多个十六进制\x