字符串比较(检查一个字符串是否以另一个字符串开头):std::string comparison

90

我需要检查一个std:string是否以“xyz”开头。如何在不搜索整个字符串或创建临时字符串的情况下完成它。

我该怎么做呢?
5个回答

163

我会使用比较方法:

std::string s("xyzblahblah");
std::string t("xyz")

if (s.compare(0, t.length(), t) == 0)
{
// ok
}

3
为什么不直接使用 s.compare(t)? - Franck Mesirard
5
这是因为默认情况下_compare_会尝试将传递的整个字符串长度与成员数据进行比较,并返回false,而将长度作为传递参数会使其返回true(这意味着当使用偏移量和长度时, std :: basic_string :: compare 可以像其他库中的String.BeginsWith()一样使用)。如果没有偏移量和长度,则不会出现这种情况。 - legends2k
1
如果 t 为空,则返回 true。 - gliderkite
14
@gliderkite 提到,空字符串是每个字符串的一个初始前缀,这是正确的。 - Jim Balter
1
如果你想排除空字符串,那么正确的做法是:if (!t.empty() && !s.compare(0, t.length(), t)) - ericcurtin
显示剩余3条评论

14

一个更符合标准库精神的方法是定义你自己的begins_with算法。

#include <algorithm>
using namespace std;


template<class TContainer>
bool begins_with(const TContainer& input, const TContainer& match)
{
    return input.size() >= match.size()
        && equal(match.begin(), match.end(), input.begin());
}

这提供了一个更简单的接口给客户端代码,并且与大多数标准库容器兼容。


酷!这应该被添加以提升! - David
2
@David: 如果允许使用boost库,可以查看boost::algorithm::starts_with函数,该函数可用于判断字符串前缀是否匹配。 - Gabor

10

查看Boost的String Algo库,其中包含许多有用的功能,例如starts_with、istart_with(不区分大小写)等。如果你想在项目中只使用部分Boost库,那么可以使用bcp实用程序仅复制所需文件。


4

似乎C++20中包含了std::string::starts_with函数,但是也可以使用std::string::find函数。

std::string s1("xyzblahblah");
std::string s2("xyz")

if (s1.find(s2) == 0)
{
   // ok, s1 starts with s2
}

1
这比使用std::string::compare的被接受答案要好得多,因为它使得检查字符串是否以字面量开头变得容易,而不需要重复字面量本身来找到其大小。感谢您指出C++20的直接解决方案。 - Ruslan
如果s1不以s2开头,这段代码仍会尝试匹配它,这不如使用compare()函数好。 - A117

0

我感觉我没有完全理解你的问题。看起来这应该是微不足道的:

s[0]=='x' && s[1]=='y' && s[2]=='z'

这只查看(最多)前三个字符。对于在编译时未知的字符串的泛化需要您用循环替换上述内容:

// look for t at the start of s
for (int i=0; i<s.length(); i++)
{
  if (s[i]!=t[i])
    return false;
}

6
如果 t 比 s 更短,那会怎样呢? - vidstige
1
@vidstige 当循环遇到t中的终止NUL时,循环终止。 - Jim Balter
@Neutrino 问题不在于Stepanov关于面向对象编程的正确与否,而在于STL是否是面向对象的。(当然它不是。) - Jim Balter
@JimBalter 我认为这是有争议的。STL类通过一个接口暴露它们的功能,接口背后隐藏了私有实现,它们可以像其他面向对象类型一样被组合和子类化。由于它们是通用的,它们的接口并不能完全隔离客户端与它们的实现,但我不认为这意味着它们根本不是面向对象的。 - Neutrino
当STL的创造者说STL不是面向对象时,这是毫无争议的...当上述论点是彻头彻尾的胡说八道时;STL容器被实现为C++类并不意味着STL是面向对象的。 - Jim Balter
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接