此表达式有效吗



我遇到过这个代码:

std::string str;
std::getline(std::cin, str);
std::string sub = str.substr(str.find('.') + 1);

第一反应是-这是无效代码。但经过思考,事情似乎并没有那么简单。那么它是有效的C++表达式(具有可预测的行为)吗?

PS如果不是那么清楚的话,这个问题主要和什么时候会发生有关不会在str中找到,但不限于此,因为可能存在其他问题。

str.find('.')返回字符串中第一个出现的字符的索引。带有一个参数的substr返回从给定索引开始的字符串的后缀。因此,该行的作用是返回从第一个点开始的字符串尾部。因此,如果str"hello.good.bye",则sub将是good.bye

但是,如果字符串实际上不包含任何点,则代码可能存在问题。它将返回整个字符串。这可能是有意的,也可能不是有意的。发生这种情况是因为如果没有点,find将返回npos,这是std::string::size_type可以容纳的最大数字。加上1,你会得到0(这就是无符号类型的行为,模2n)。

因此,代码总是具有可预测的行为。

来源http://en.cppreference.com/w/cpp/string/basic_string/npos似乎CCD_ 12。当find不成功时,会返回该值。在这种情况下,str.substr(0)将返回整个字符串。

这似乎是一个有效且可预测的代码。

如果您询问如果找不到.会发生什么,您不必担心。std::string::find然后返回std::string::npos,标准将其定义为-1,在添加1之后,CCD_17溢出并使参数0:

std::string sub = str.substr(0);

这就给了你完整的线索。我不知道这是否是想要的行为,但这肯定不是未定义的行为。

实际上,在这种特定情况下——因为包含"…无关紧要…"的字符串实际上是重要的——find()调用找不到它要查找的内容,因此将返回std::string::npos。然后再添加1。

npos的类型是std::string::size_type,通常是size_t,通常是某种类型的无符号整数

25被定义为CCD_ 26的最大可能值。

size_type是无符号的,在最大可能值上加1会产生0。

所以你打电话给std::string::substr(0)。这是干什么的?它会创建您调用它的整个字符串的副本,因为substr具有起始位置和长度(默认为npos,或"一直到结尾")。

据我所见,它是有效的,尽管它不是特别可读。

如果str为空,则find()方法将返回std::string::npos。这相当于CCD_ 35所代表的最大CCD_。通过向其中添加1,您将导致整数溢出,并且它将环绕到0。这意味着substr()方法试图使用从位置0到字符串末尾的字符创建字符串。如果str为空,则sub也为空。

相关内容

  • 没有找到相关文章

最新更新