6

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

我的推理是,如果""包含另一个"",那一个也会包含""等等。

谁错了?

附言

我在谈论一个std::string

PSPS

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

编辑:

我是唯一一个认为该功能有问题的人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;

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

4

7 回答 7

16

这取决于您所说的“包含”是什么意思。

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

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

关于集合,集合

{2}

是集合的一个

A = {1, 2, 3}

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

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

所以你们俩都是对的。

于 2013-08-01T15:04:20.300 回答
8

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

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

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

输出:"" contains "": true

演示

于 2013-08-01T14:59:30.313 回答
4

这很简单。offset如果存在这样的参数,则字符串 A 包含子字符串A.substr(offset, B.size()) == BB。不需要空字符串的特殊情况。

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

于 2013-08-02T07:39:57.700 回答
0

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

于 2013-08-01T14:54:45.110 回答
0

不清楚的第一件事是您是在谈论std::string还是以空结尾的 C 字符串,第二件事是为什么重要?. 我会假设std::string

确定组件必须如何表现的要求std::string,而不是其内部表示必须是什么(尽管某些要求会影响内部表示)。只要满足组件的要求,它是否在内部包含某些东西是您甚至可能无法测试的实现细节。

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

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

于 2013-08-01T14:52:04.960 回答
0

当然,空字符串不包含空字符串。如果是这样,那将是乌龟。

String empty = "";声明一个为空的字符串文字为例,如果您想要一个字符串文字来表示一个为空的字符串文字,您将需要String representsEMpty = """";,但当然,您需要转义它,给您string actuallyRepresentsEmpty = "\"\"";

ps,我对此采取务实的态度。把数学废话留在门口。

考虑到您的修改,您的“对手”可能意味着“空” std::string 仍然有一个内部存储的字符,而该字符本身是空的。我敢肯定,这将是一个实现细节,它可能只保留一定大小(比如 10 个)的字符数组“只是以防万一”,所以它在技术上不会是空的。

当然,有一个技巧问题的答案是“没有”适合任何无限次的东西,一种“除以零”的情况。

于 2013-08-01T14:50:16.377 回答
0

今天我有同样的问题,因为我目前绑定到一个糟糕的 STL 实现(可以追溯到 C++98 之前的时代),它不同于 C++98 和以下所有标准:

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

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

在 Cppreference 上,我在std::basic_string::find中看到了关于空字符串的明确描述,我认为该描述与所讨论的情况完全匹配:

当且仅当 pos <= 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());

这种对“包含”的解释以“是”回答了这个问题。

于 2017-09-07T09:44:06.570 回答