substr会改变find函数开始搜索的位置吗?

时间:2019-06-07 12:59:34

标签: c++ string find substr

substr是否更改find​​函数开始搜索的位置?

我有一个名为* search_text的字符,其中包含以下文本:

ABC_NAME = 'XYZSomeone' AND ABC_CLASS = 'XYZSomething'

我要显示该字符串中的“ ABC_NAME”值。

这是我在做什么:

std::cout << std::string(search_text).substr ( 12, std::string( search_text ).find ("'", 13 )-1) << std::endl;

我在上面的substr中的逻辑如下:

  1. ABC_NAME值始终从第12个字符开始,因此从此处开始子字符串。
  2. 从第13个字符(find()函数的第二个参数)开始,从第13个字符开始查找字符'(单引号)。结果数字将是子字符串的外边界。

但是,我的代码显示了以下内容:

XYZSomeone' AND ABC_C

但是,当我尝试直接显示find()函数的值时,我确实获得了第二个'(单引号)位置的正确数字

std::cout << std::string( search_text ).find ("'", 13 ) << std::endl;

打印输出:

22

那么为什么substr找不到22的值作为第二个参数?

1 个答案:

答案 0 :(得分:0)

手动评估表达式很简单,看看您已经如何验证find的结果:

std::string(search_text).substr ( 12, std::string( search_text ).find ("'", 13 )-1)
std::string("ABC_NAME = 'XYZSomeone' AND ABC_CLASS = 'XYZSomething'").substr ( 12, 22-1)

现在检查documentation for substr“返回子字符串[pos,pos + count)” 。位置12处的字符是名称部分的'X',位置12 + 21 = 33处的字符是类部分的'L'。因此,我们期望子字符串从该'X'开始,一直到该'L'之前的"XYZSomeone' AND ABC_C"。检查。

(忘记substr是长度还是结束位置是可以理解的。不同的语言对此有不同意见。因此链接到文档。)

未经请求的评论

尝试在一行中做很多事情会使您的代码更难阅读和调试。在这种情况下,也会损害性能。无需将search_text转换为std::string两次。

std::string search_string{search_text};
std::size_t found = search_string.find('\'', 12);
if ( found != std::string::npos )
    found -= 12;
std::cout << search_string.substr(12, found) << std::endl;

这将构造字符串的次数(因此,复制字符串数据的次数)从三倍减少到两倍。

如果使用的是C ++ 17,则可以通过不构造任何字符串来进一步提高性能。只需使用std::string_view而不是std::string。对于这种情况,它具有采用相同参数的相同成员函数。您只需更改search_string的类型即可。这使性能与C代码相当。

甚至更好:由于字符串视图的创建非常便宜,因此您甚至可以编写代码(而不会影响性能),因此substr是否需要一段长度或是否过去都无济于事-结束位置。

std::string_view search_string{search_text};
std::string_view ltrimmed = search_string.substr(12);
std::size_t found = ltrimmed.find('\'');
std::cout << ltrimmed.substr(0, found) << std::endl;

建设性懒惰FTW!