在c++中,如何知道字符串是否以另一个字符串结束?
当前回答
如果你像我一样,对c++的纯粹主义不那么感兴趣,这里有一个古老的混合体。当字符串多于几个字符时,会有一些优势,因为大多数memcmp实现都尽可能比较机器单词。
你需要控制字符集。例如,如果这种方法与utf-8或wchar类型一起使用,则会有一些缺点,因为它不支持字符映射——例如,当两个或多个字符在逻辑上相同时。
bool starts_with(std::string const & value, std::string const & prefix)
{
size_t valueSize = value.size();
size_t prefixSize = prefix.size();
if (prefixSize > valueSize)
{
return false;
}
return memcmp(value.data(), prefix.data(), prefixSize) == 0;
}
bool ends_with(std::string const & value, std::string const & suffix)
{
size_t valueSize = value.size();
size_t suffixSize = suffix.size();
if (suffixSize > valueSize)
{
return false;
}
const char * valuePtr = value.data() + valueSize - suffixSize;
return memcmp(valuePtr, suffix.data(), suffixSize) == 0;
}
其他回答
注意,从c++20开始std::string将最终提供starts_with和ends_with。看起来c++中的字符串有可能最终变得可用,如果你不是在遥远的将来读到这篇文章,你可以在c++ 17中使用这些startsWith/endsWith:
#if __cplusplus >= 201703L // C++17 and later
#include <string_view>
static bool endsWith(std::string_view str, std::string_view suffix)
{
return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix);
}
static bool startsWith(std::string_view str, std::string_view prefix)
{
return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
}
#endif // C++17
如果你坚持使用旧的c++,你可以使用这些:
#if __cplusplus < 201703L // pre C++17
#include <string>
static bool endsWith(const std::string& str, const std::string& suffix)
{
return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix);
}
static bool startsWith(const std::string& str, const std::string& prefix)
{
return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
}
并且一些额外的helper会重载:
static bool endsWith(const std::string& str, const char* suffix, unsigned suffixLen)
{
return str.size() >= suffixLen && 0 == str.compare(str.size()-suffixLen, suffixLen, suffix, suffixLen);
}
static bool endsWith(const std::string& str, const char* suffix)
{
return endsWith(str, suffix, std::string::traits_type::length(suffix));
}
static bool startsWith(const std::string& str, const char* prefix, unsigned prefixLen)
{
return str.size() >= prefixLen && 0 == str.compare(0, prefixLen, prefix, prefixLen);
}
static bool startsWith(const std::string& str, const char* prefix)
{
return startsWith(str, prefix, std::string::traits_type::length(prefix));
}
#endif
在我看来,c++字符串显然是功能失调的,而且不适合在现实世界的代码中使用。但至少有希望情况会有所好转。
我认为发布一个不使用任何库函数的原始解决方案是有意义的…
// Checks whether `str' ends with `suffix'
bool endsWith(const std::string& str, const std::string& suffix) {
if (&suffix == &str) return true; // str and suffix are the same string
if (suffix.length() > str.length()) return false;
size_t delta = str.length() - suffix.length();
for (size_t i = 0; i < suffix.length(); ++i) {
if (suffix[i] != str[delta + i]) return false;
}
return true;
}
添加一个简单的std::tolower,我们可以使这种情况不敏感
// Checks whether `str' ends with `suffix' ignoring case
bool endsWithIgnoreCase(const std::string& str, const std::string& suffix) {
if (&suffix == &str) return true; // str and suffix are the same string
if (suffix.length() > str.length()) return false;
size_t delta = str.length() - suffix.length();
for (size_t i = 0; i < suffix.length(); ++i) {
if (std::tolower(suffix[i]) != std::tolower(str[delta + i])) return false;
}
return true;
}
bool endswith(const std::string &str, const std::string &suffix)
{
string::size_type totalSize = str.size();
string::size_type suffixSize = suffix.size();
if(totalSize < suffixSize) {
return false;
}
return str.compare(totalSize - suffixSize, suffixSize, suffix) == 0;
}
设a是一个字符串,b是你要找的字符串。使用a.s ustr获取a的最后n个字符,并将它们与b进行比较(其中n是b的长度)
或者使用std::equal (include <algorithm>)
Ex:
bool EndsWith(const string& a, const string& b) {
if (b.size() > a.size()) return false;
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
}
bool EndsWith(const std::string& data, const std::string& suffix)
{
return data.find(suffix, data.size() - suffix.size()) != std::string::npos;
}
测试
#include <iostream>
int main()
{
cout << EndsWith(u8"o!hello!1", u8"o!") << endl;
cout << EndsWith(u8"o!hello!", u8"o!") << endl;
cout << EndsWith(u8"hello!", u8"o!") << endl;
cout << EndsWith(u8"o!hello!o!", u8"o!") << endl;
return 0;
}
输出
0
1
1
1
推荐文章
- decltype(auto)的一些用途是什么?
- Shared_ptr转换为数组:应该使用它吗?
- Printf与std::字符串?
- 禁用复制构造函数
- 不区分大小写的“in”
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 只接受特定类型的c++模板
- 如何在PHP中截断字符串最接近于一定数量的字符?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- Ruby数组到字符串的转换
- c++ 11中的递归lambda函数
- 在c++中指针使用NULL或0(零)吗?
- 为什么在Java和。net中不能修改字符串?
- 在c++中,如何将int值附加到字符串中?
- 如何创建一个日期对象从字符串在javascript