这个问题来自于this answer的讨论。
简而言之:答案的作者(0x499602D2)声称(正确地,正如我现在所知),当不跳过空格,但下一个字符是空格时,除字符外的所有提取都将失败。
我在基础上质疑这一点,我认为提取string
不应该失败,因为流包含一个由开头的空白字符分隔的空字符串。
这引发了一般性讨论,无论字符串中的任何位置是否有空字符串,例如在字符串a
的{{1}}和b
之间(我说是,0x499602D2表示否)。 0x499602D2建议我把它放在一个问题中,所以我在这里。
我从该主题(包括聊天部分)复制我的主要论点:
让我们首先看一下空字符串的常量。在C和C ++中,内容在开头和结尾用引号分隔。那么空字符串是什么样的?你知道的:
"ab"
。你看,在初始引用(分隔符)之后直接跟随最终引用(分隔符)。空字符串位于两个引号之间,它们直接相互跟随,因为空字符串没有字符。另请参阅C表示。这是字符序列,后跟分隔符' \ 0'。那么空字符串的表示是什么?好吧,空字符串的字符后跟分隔符。这意味着,第一个字符是分隔符(即,与流情况完全相同)。现在考虑串的串联,例如第一个字符串是""
,第二个字符串是空的,第三个字符串是"a"
。那么连接是什么?好吧,"b"
。很明显,"ab"
中的a
和b
之间有一个空字符串(我们明确地将它放在那里!)。当然,在"ab"
之前和a
之后也是如此。也就是说,字符串的任意两个字符之间都有一个空字符串(或两个或一百万个)。空字符串没有字符,连续字符之间没有字符。因此,在两个字符之间有一个空字符串。另请参阅我之前给出的其他论据。另外,考虑与空字符串匹配的正则表达式:它们也匹配到处。 例如,
b
匹配/ab*c/
,因为"ac"
匹配b*
和a
之间的空字符串在分隔符(空格)之前有一个空字符串(即没有字符),就像在空字符串的C表示中一样,
c
分隔符之前没有字符。另请注意,\0
也与readline
分隔符的工作方式相同:如果\n
立即跟随,则它不会失败,但会给出一个空字符串。
我觉得无法在讨论中找出0x499602D2的主要论点,所以我不会试图避免在选择中无意中不公平。您应该能够在评论中看到它们(可能还有聊天室 - 我不知道每个人都可以访问它们)。 @ 0x499602D2:如果您愿意,您也可以在本段后面添加主要参数。
与此相关的实际问题是:如果分隔符之前没有字符(如字符串\n
那样),则设计良好的字符串提取函数是否会失败,或者成功并返回空字符串(如{ {1}}确实如此)?
答案 0 :(得分:10)
<强>定理强>
字符串 s 中的任何位置都有一个空字符串ε。
<强>证明强>
1。如果| s | = 0( s 的长度为零),然后 s = ε,声明成立。
2. 如果| s | &GT; 0,则 s 有两个边缘位置:第一个符号前一个,后一个符号后另一个。由于ε是连接操作的标识元素,即εs = sε = s ,声明适用于开始和结束位置。
3. 如果| s | &GT; 1,然后 s 可以写成两个非空字符串的串联: s = pq ,其中| p | &GT; 0和| q | &GT; 0.使用ε的identity元素属性, p ε q = (p ε)q = pq = s ,这意味着声明适用于 s 中的位置,该位置将其分为部分p 和 q 。该分部的位置可以是 s 的任何内部位置,因此该声明也适用于每个内部职位。
推论
标识元素属性意味着ε = εε = εεε =等。在替换ε后重复上述证据 with ε^ n ,其中 n 是一个正整数,我们发现在任何字符串的任何位置都有无数个空字符串。
备注强>
这里“位置”一词的意思是“插入位置”(text insertion cursor位置)。插入符号可以放在第一个符号(索引:0)之前,连续符号之间和最后一个符号之后(索引:| s |)。插入位置的数量为| s | + 1.
上述证明表明,符号之间的这些“零宽度间隙”可以设想为填充任意数量的空字符串。 (这就像空集是每个集合的子集一样奇怪,包括它自己。)