读取字符串最后一行的最快方法?

fastest way to read the last line of a string?

我想知道读取 std::string 对象最后一行的最快方法。
从技术上讲,最后一次出现 \n 之后的字符串以最快的方式出现?

我想到了一种在存储读取内容的同时反向(向后)读取字符串的方法

std::string get_last_line(const std::string &str)
{
    size_t l = str.length();
    std::string last_line_reversed, last_line;
    for (--l; l > 0; --l)
    {
        char c = str.at(l);
        if (c == '\n')
            break;
        last_line_reversed += c;
    }
    l = last_line_reversed.length();
    size_t i = 0, y = l;
    for (; i < l; ++i)
        last_line += last_line_reversed[--y];
    return last_line;
}

直到它反击一个 '\n' 字符,然后将存储的字符串反向并 return 它。如果目标字符串很大并且有很多新行,这个函数会非常有效。

这可以只使用 string::find_last_ofstring::substr 来完成,就像这样

std::string get_last_line(const std::string &str)
{
  auto position = str.find_last_of('\n');
  if (position == std::string::npos)
    return str;
  else
    return str.substr(position + 1);
}

参见:example

我可能会使用 std::string::rfind and std::string::substr combined with guaranteed std::string::npos 环绕来简洁:

inline std::string last_line_of(std::string const& s)
{
    return s.substr(s.rfind('\n') + 1);
}

如果 s.rfind('\n') 没有找到任何东西,它 return 就会 std::string::nposC++ 标准表示 std::string::npos + 1 == 0。 returning s.substr(0) 总是安全的。

如果 s.rfind('\n') 确实找到了某些内容,那么您需要从下一个字符开始的子字符串。再次 returning s.substr(s.size()) 根据标准是安全的。

注意:C++17中,此方法将受益于保证return值优化,因此它应该是超级高效。