空字符串在C ++中是否包含空字符串?

时间:2013-08-01 14:44:28

标签: c++ string contains portability text-processing

在我的一个问题的评论中有一个有趣的论点。我的对手声称""声明包含""是错误的。

我的理由是,如果""包含另一个"",那个人还会包含"",依此类推。

谁错了?

P.S。

我说的是std::string

P.S。 P.S

我不是在谈论子串,但即使我将我的问题“添加为子串”,它仍然没有意义。空子字符串是无意义。如果允许空字符串包含在字符串中,则意味着您具有无限的空子字符串。有什么意义呢?

编辑:

我是唯一一个认为函数std::string::find出错的人吗?

C ++参考清楚地说

  

返回值:第一个匹配的第一个字符的位置。

好的,让我们假设一分钟就有意义并运行此代码:

string empty1 = "";
string empty2 = "";

int postition = empty1.find(empty2);

cout << "found \"\" at index " << position << endl;

输出为:found "" at index 0

无意义的部分:如何在长度为0的字符串中存在索引0?这是无稽之谈。

为了能够拥有第0个位置,该字符串的长度必须至少为1个字符。

在这种情况下,C ++给出了一个例外,这证明了我的观点:

cout << empty2.at( empty1.find(empty2) ) << endl;

如果它真的包含一个空字符串,那么将其打印出来没有问题。

7 个答案:

答案 0 :(得分:15)

这取决于你所说的“包含”。

空字符串是空字符串的子字符串,因此包含在那个意义上。

另一方面,如果将字符串视为字符集合,则空字符串不能包含空字符串,因为其元素是字符,而不是字符串。

关于集合,集合

{2}

是集合

子集
A = {1, 2, 3}

{2}不是A成员 - 所有A的成员都是数字,而不是集合。

同样,{}{}的子集,但{}不是{}中的元素(不能因为它是空的)。

所以你们都是对的。

答案 1 :(得分:7)

C ++同意你的“对手”:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    bool contains = string("").find(string("")) != string::npos;
    cout << "\"\" contains \"\": "
        << boolalpha << contains;
}

输出:"" contains "": true

Demo

答案 2 :(得分:4)

这很容易。如果存在offset参数A.substr(offset, B.size()) == B,则字符串A包含子字符串B.没有特殊情况需要空字符串。

所以,让我们看看。 std::string("").substr(0,0)原来是std::string("")。我们甚至可以检查你的“反例”。 std::string("").substr(0,0).substr(0,0)也是定义明确且空洞的。乌龟一路下来。

答案 3 :(得分:0)

当然,空字符串不包含空字符串。如果确实如此,那将是乌龟。

String empty = "";声明为空字符串文字,如果您希望字符串文字表示字符串文字为空,则需要String representsEMpty = """";但是当然,你需要逃避它,给你string actuallyRepresentsEmpty = "\"\"";

ps,我采取务实的方法。把数学废话留在门口。

考虑到你的修正,你的'对手'可能意味着'空'std :: string仍然有一个内部存储空间,这些字符本身没有字符。这将是一个实现细节,我肯定,它可能只是保持一定的大小(比方说10)字符数组'只是加入',所以它在技术上不会是空的。

当然,有一个技巧问题的答案是“无所谓”适用于任何无限的时间,一种“零分割”的情况。

答案 4 :(得分:0)

首先不清楚的是你是在讨论std::string还是空终止的C字符串,第二件事是为什么它应该重要?。我将假设std::string

std::string的要求决定了组件必须如何行为,而不是其内部表示必须是什么(尽管某些要求会影响内部表示)。只要满足组件的要求,它是否在内部保存某些内容就是您可能无法测试的实现细节。

在空字符串的特定情况下,没有任何东西要求它保存任何东西。它可以只将一个size成员设置为0,并且指针(对于动态分配的内存,如果/非空)也设置为0. operator[]中的要求要求它返回对值为0的字符的引用,但由于在不导致未定义的行为的情况下无法修改该字符,并且由于严格的别名规则允许从char类型的左值读取,因此实现可以只返回对size成员中的一个字节的引用(所有集合)在空字符串的情况下为0)。

std::string的某些实现使用小对象优化,在这些实现中,将为小字符串保留内存,包括 empty 字符串。虽然std::string内部显然不包含std::string,但它可能包含组成空字符串的字符序列(即终止空字符)

答案 5 :(得分:0)

空字符串不包含任何内容 - 它是EMPTY。 :)

答案 6 :(得分:0)

今天我遇到了同样的问题,因为我目前已经接受了糟糕的STL实现(可追溯到C ++ 98之前的时代),这与C ++ 98和以下所有标准不同:

TEST_ASSERT(std::string().find(std::string()) == string::npos); // WRONG!!! (non-standard)

如果您尝试编写可移植代码,这尤其糟糕,因为很难证明任何功能都不依赖于该行为。遗憾的是,在我的情况下确实如此:它根据用户线规范进行字符串处理以缩短电话号码输入。

在Cppreference上,我在std::basic_string::find中看到一个关于空字符串的明确描述,我认为这些字符串恰好与所讨论的情况相符:

  

当pos且仅当pos&lt; = size()

时,在pos处找到一个空子串

引用的pos定义了开始搜索的位置,默认为0(开头)。

符合标准的 C ++标准库将通过以下测试:

TEST_ASSERT(std::string().find(std::string()) == 0);
TEST_ASSERT(std::string().substr(0, 0).empty());
TEST_ASSERT(std::string().substr().empty());

对&#34;的解释包含&#34;用是来回答这个问题。