C++ 标准库中缺少的字符串函数:`starts_with` 和 `ends_with`

这是一篇简短的记录。

C++ 标准模板库的 std::string 很好很强大,但是并没有提供判断一个字符串是否以另一个字符串开始/结束的接口。这里为 std::basic_string<charT> 提供这两个接口。

string_predicate.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
namespace std {
template <typename charT>
inline bool starts_with(const basic_string<charT>& big, const basic_string<charT>& small) {
if (&big == &small) return true;
const typename basic_string<charT>::size_type big_size = big.size();
const typename basic_string<charT>::size_type small_size = small.size();
const bool valid_ = (big_size >= small_size);
const bool starts_with_ = (big.compare(0, small_size, small) == 0);
return valid_ and starts_with_;
}

template <typename charT>
inline bool ends_with(const basic_string<charT>& big, const basic_string<charT>& small) {
if (&big == &small) return true;
const typename basic_string<charT>::size_type big_size = big.size();
const typename basic_string<charT>::size_type small_size = small.size();
const bool valid_ = (big_size >= small_size);
const bool ends_with_ = (big.compare(big_size - small_size, small_size, small) == 0);
return valid_ and ends_with_;
}
} // namespace std

用法:

test.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>

#include "string_predicate.hpp"

int main() {
std::string compared = "Hello world!";
std::string start = "Hello";
std::string end = "world!";

std::cout << std::starts_with(compared, start) << std::endl;
std::cout << std::ends_with(compared, end) << std::endl;

std::wstring wcompared = L"你好世界";
std::wstring wstart = L"你好";
std::wstring wend = L"世界";

std::cout << std::starts_with(wcompared, wstart) << std::endl;
std::cout << std::ends_with(wcompared, wend) << std::endl;

return 0;
}

结果:

1
2
3
4
5
6
$ g++ test.cc
$ ./a.out
1
1
1
1

您的鼓励是我写作最大的动力

俗话说,投资效率是最好的投资。 如果您感觉我的文章质量不错,读后收获很大,预计能为您提高 10% 的工作效率,不妨小额捐助我一下,让我有动力继续写出更多好文章。


撰写评论

写了这么多年博客,收到的优秀评论少之又少。在这个属于 SNS 的时代也并不缺少向作者反馈的渠道。因此,如果你希望撰写评论,请发邮件至我的邮箱并注明文章标题,我会挑选对读者有价值的评论附加到文章末尾。