【发布时间】:2011-11-11 14:06:21
【问题描述】:
在 C++ 中有什么方法可以检查字符串是否以某个字符串开头(小于原始字符串)?就像我们在 Java 中可以做的那样
bigString.startswith(smallString);
【问题讨论】:
-
你说的是C字符串还是std::String
-
我说的是 C++ string.std::string
在 C++ 中有什么方法可以检查字符串是否以某个字符串开头(小于原始字符串)?就像我们在 Java 中可以做的那样
bigString.startswith(smallString);
【问题讨论】:
std::string s("Hello world");
if (s.find("Hello") == 0)
{
std::cout << "String starts with Hello\n";
}
【讨论】:
O(min(bigString.length(), smallString.length()))
smallString 不长于bigString,则只需比较前smallString.size() 个字符即可知道答案;除了在初始位置之外,您不必搜索整个 bigString 以查找 smallString。
您可以使用string::compare() 执行此操作,它提供了用于比较两个字符串的全部或部分的各种选项。此版本将smallString 与bigString 的适当大小前缀进行比较(如果bigString 比smallString 短,则可以正常工作):
bigString.compare(0, smallString.length(), smallString) == 0
我倾向于将其封装在一个名为 startsWith() 的免费函数中,否则它看起来会有点神秘。
更新:C++20 is adding 新增 starts_with 和 ends_with 函数,因此您最终将能够只编写 bigString.starts_with(smallString)。
【讨论】:
使用string::find() 或string::substr() 的方法不是最优的,因为它们要么复制你的字符串,要么在字符串的开头搜索多个匹配项。在您的情况下,这可能不是问题,但如果是,您可以使用 std::equal 算法。记得检查“干草堆”至少和“针”一样长。
#include <string>
using namespace std;
bool startsWith(const string& haystack, const string& needle) {
return needle.length() <= haystack.length()
&& equal(needle.begin(), needle.end(), haystack.begin());
}
【讨论】:
一如既往,正确的解决方案来自 Boost:boost::algorithm::starts_with。
【讨论】:
稍微优化一下:
if ( smallString.size() <= bigString.size() &&
strncmp( smallString.c_str(), bigString.c_str(), smallString.length() ) == 0 )
别忘了#include <cstring> 或#include <string.h>
【讨论】:
对于 C++20,您可以使用 std::basic_string::starts_with(或 std::basic_string_view::starts_with):
#include <string_view>
std::string_view bigString_v("Winter is gone"); // std::string_view avoids the copy in substr below.
std::string_view smallString_v("Winter");
if (bigString_v.starts_with(smallString_v))
{
std::cout << "Westeros" << bigString_v.substr(smallString_v.size());
}
【讨论】:
最简单的方法是:
if ( smallString.size() <= bigString.size()
&& std::equals( smallString.begin(), smallString.end(), bigString.end() )
(如果两者之一或两者都是向量,这也将起作用。或任何 其他标准容器类型。)
【讨论】:
std::equal,应该是bigString.end()。
strstr() 返回指向字符串中第一次出现的字符串的指针。
【讨论】:
我认为发布一个不使用任何库函数的原始解决方案是有意义的......
// Checks whether `str' starts with `start'
bool startsWith(const std::string& str, const std::string& start) {
if (&start == &str) return true; // str and start are the same string
if (start.length() > str.length()) return false;
for (size_t i = 0; i < start.length(); ++i) {
if (start[i] != str[i]) return false;
}
return true;
}
添加一个简单的std::tolower 我们可以使这个不区分大小写
// Checks whether `str' starts with `start' ignoring case
bool startsWithIgnoreCase(const std::string& str, const std::string& start) {
if (&start == &str) return true; // str and start are the same string
if (start.length() > str.length()) return false;
for (size_t i = 0; i < start.length(); ++i) {
if (std::tolower(start[i]) != std::tolower(str[i])) return false;
}
return true;
}
【讨论】:
要么创建一个子字符串,它是您的smallString 变量的长度,然后比较两者。或者搜索子字符串smallString,看看它是否返回索引0
【讨论】:
http://www.cplusplus.com/reference/string/string/substr/
您可以使用 string.substr() 从任何位置查看任意数量的字符,也可以使用 string.find() 成员。
【讨论】: