gpt4 book ai didi

c++ - 可以使用 C++20 范围就地修剪字符串吗?

转载 作者:行者123 更新时间:2023-12-05 01:07:50 24 4
gpt4 key购买 nike

灵感来自可爱的 cppreference example使用 C++20 进行修剪我编写了以下代码(我已将返回类型更改为 void 并将 arg 更改为 std::string& 因为我的“问题”(我我正在发明问题来学习 C++20)在使用 std::string_view arg 并返回 std::string 的原始代码中不存在)。

void trim(std::string&  in)
{
auto view
= std::views::all(in)
| std::views::drop_while(isspace)
| std::views::reverse
| std::views::drop_while(isspace)
| std::views::reverse;
std::string result{view.begin(), view.end()};
in = std::move(result);
}

这里的问题是这不是就地的,这意味着创建了新字符串。我可以编写更丑陋的代码来就地执行此操作,而且我知道传统的 C++ 算法不知道容器的存在,但我想知道 C++20 是否有一些技巧可以让我以优雅的方式进行修剪,但也是就地的。

这也是我丑陋的就地修剪(不确定它是否可以正常工作,但想法是它会就地修剪):

void trim2(std::string& s) {
// ugly and error prone, but inplace
const auto it1 = std::ranges::find_if_not(s, isspace);
const auto it2 = std::ranges::find_if_not(s.rbegin(), s.rend(), isspace);
const size_t shift = (it1==s.end()) ? 0: std::distance(s.begin(), it1);
const size_t result_size = s.size() - shift - ((it2==s.rend()) ? 0 : std::distance(s.rbegin(), it2));
std::shift_left(s.begin(), s.end(), shift);
s.resize(result_size);
}

godbolt

edit:最初这个问题声称 in.assign 将是 UB,但 T.C.纠正了我。但根据我对 C++23 草案分配的理解,仍然会导致创建临时字符串。

最佳答案

也许是这样的?

void trim(std::string& s) {
auto not_space = [](unsigned char c){ return !std::isspace(c); };

// erase the the spaces at the back first
// so we don't have to do extra work
s.erase(
std::ranges::find_if(s | std::views::reverse, not_space).base(),
s.end());

// erase the spaces at the front
s.erase(
s.begin(),
std::ranges::find_if(s, not_space));
}

关于c++ - 可以使用 C++20 范围就地修剪字符串吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66897068/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com