解释字符串修剪功能

时间:2014-06-26 07:50:42

标签: c++ string c++11 c++14

我遇到了下面的代码,但需要一些帮助来理解代码。假设字符串s的两边都有空格。

string trim(string const& s){
   auto front = find_if_not(begin(s), end(s), isspace);
   auto back = find_if_not(rbegin(s), rend(s), isspace);
   return string { front, back.base() };
}

作者说,后面指向最后一个空格的末尾,而前面指向第一个非空白字符。所以 back.base()被调用了,但我不明白为什么。

在return语句中跟随字符串后,花括号是什么?

1 个答案:

答案 0 :(得分:28)

大括号是新的C ++ 11初始化。

.base()并反转迭代器

.base()是返回底层迭代器(backreverse_iterator),以便从有效范围正确构造新字符串。

一张照片。字符串的正常迭代器位置(关于rend()如何工作,它比这更复杂一点,但概念上无论如何......)

        begin                                 end
          v                                    v
        -------------------------------------
        | sp | sp | A | B | C | D | sp | sp |
        -------------------------------------
      ^                                   ^
    rend                                rbegin

一旦你的两个find循环完成,这个序列中的迭代器的结果将定位在:

                  front
                    v
        -------------------------------------
        | sp | sp | A | B | C | D | sp | sp |
        -------------------------------------
                                ^
                              back

我们是否只接受那些迭代器并从它们构造一个序列(我们不能,因为它们不匹配类型,但无论如何,我们都可以),结果将是“从A开始复制,停止在D“但在结果数据中不包括D

输入反向迭代器的back()成员。它返回一个前向迭代器类的非反向迭代器,它位于后迭代器“旁边”的元素上;即。

                  front
                    v
        -------------------------------------
        | sp | sp | A | B | C | D | sp | sp |
        -------------------------------------
                                    ^
                               back.base()

现在当我们复制我们的范围{ front, back.base() }时,我们从A开始复制并停在第一个空格(但不包括它),从而包括我们将拥有的D错过。

它实际上是一段光滑的小代码,顺便说一句。

进行一些额外检查

在原始代码中添加了一些基本检查。

在努力保持原始代码的精神(C ++ 1y / C ++ 14用法)时,只为空白和空格添加一些基本检查字符串;

string trim_check(string const& s)
{
  auto is_space = [](char c) { return isspace(c, locale()); };
  auto front = find_if_not(begin(s), end(s), is_space);
  auto back = find_if_not(rbegin(s), make_reverse_iterator(front), is_space);
  return string { front, back.base() };
}