std :: string :: substr的行为,起始位置为std :: string :: npos [关闭]

问题描述 投票:-3回答:1

C ++标准库具有许多字符串处理功能,其中之一是std::string::substr

来自cplusplus.com

返回一个新构造的字符串对象,其值初始化为该对象的子字符串的副本。

子字符串是对象的一部分,从字符位置pos开始并跨越len个字符(或直到字符串的结尾,以先到者为准)。

[一个有趣的情况是用std::string::substr调用some_string.substr(start_pos),例如:

start_pos = std::string::npos

这引发异常:

在抛出'std :: out_of_range'实例后调用终止what():basic_string :: substr:__ pos(为4294967295)> this-> size()(为6)

我希望它只是返回一个空字符串。

  • 此行为是否有任何客观原因?

    我可以认为我们不想浪费内存来创建空字符串。还有什么?代码错过了一些健全性检查:我相信打个招呼完全没问题!

  • 在什么情况下最好抛出异常?
  • 在上面的示例中,以任何方式返回空字符串是“有害”还是“不良”?

参考:

// We have a sentence. std::string greeting = "Hello!"; // Skip the first word. std::cout << greeting.substr(greeting.find(" ")); // Oops! "greeting" has only one word. 据说范围太广,主要基于意见。因此,我尝试提出更严格的问题(第2点和第3点)。


编辑:由于第2点和第3点有些主观,让我们尝试澄清一下:

“ Preferable”意味着其他方式应该是不直观的,并且可能是扭曲和混乱的。

示例:文件打开失败时引发例外。而不是检查它是否存在,然后将其打开。

“坏”“有害”,如代码气味。这是龙。

示例:深度嵌套的控制流,魔术常数和重复复制的代码。

c++ string substring
1个回答
0
投票

在上面的示例中,以任何方式返回空字符串是“有害”还是“不良”?

考虑这种情况:

Why does std::string::substr throw an exception instead of returning an empty string? [closed]

现在有两种情况:size_t calculate_length(); size_t calculate_pos(); std::string x{"Hello World"}; auto sub = x.substr( calculate_pos() , calculate_length() ); 都返回范围内的值,并且一切都很好。如果不是,则calculate_pos允许我识别它(我得到了例外)。

如果string::substr会为x.substr越界返回一个空字符串,那么当pos时,我将无法分辨calculate_pos越界。这似乎没有用处,但是为什么要使界面变得比必要的更为复杂呢?这样,第二个参数的任何值都可以。那是一件好事。

进一步考虑,如果您不想为潜在的例外支付费用,则不必这样做。 calculate_length() == 0的构造函数带有两个迭代器,可以有效地实现相同的效果

std::string

没有安全网。如果您得到错误的范围,则您有不确定的行为。

根据您的需要,您可以在构造函数(您绝对确定您具有有效范围)和调用auto begin = calculate_pos(); auto end = begin + calculate_length(); std::string sub{x.begin() + begin, x.begin() + end}; (您需要范围检查)之间进行选择。但是,通常需要避免使用也可能是正确结果的前哨值(空字符串)。

© www.soinside.com 2019 - 2024. All rights reserved.