有没有办法在C++中实现Python的"separator".join()的模拟?
Is there a way to implement analog of Python's 'separator'.join() in C++?
我只找到了boost::algorithm::string::join
。然而,只将Boost用于联接似乎有些过头了。所以也许有一些经过时间考验的食谱?
更新:
对不起,问题说明不正确。我正在寻找用分隔符连接字符串的方法,而不仅仅是一个接一个地连接。
由于您正在寻找配方,请继续使用Boost中的配方。一旦你克服了所有的通用性,它就不会太复杂:
- 分配一个存储结果的位置
- 将序列的第一个元素添加到结果中
- 如果还有其他元素,请将分隔符和下一个元素追加到结果中
- 返回结果
这是一个在两个迭代器上工作的版本(与Boost版本相反,Boost版本在范围上操作。
template <typename Iter>
std::string join(Iter begin, Iter end, std::string const& separator)
{
std::ostringstream result;
if (begin != end)
result << *begin++;
while (begin != end)
result << separator << *begin++;
return result.str();
}
如果您真的想要''.join()
,可以将std::copy
与std::ostream_iterator
到std::stringstream
一起使用。
#include <algorithm> // for std::copy
#include <iterator> // for std::ostream_iterator
#include <sstream> // for std::stringstream
std::vector<int> values(); // initialize these
std::stringstream buffer;
std::copy(values.begin(), values.end(), std::ostream_iterator<int>(buffer));
这将向buffer
插入所有值。您也可以为std::ostream_iterator
指定一个自定义分隔符,但它将被附加在末尾(这是与join
的显著区别)。如果您不需要分隔符,这将满足您的需要。
简单地说,其中容器中的类型是int:
std::string s = std::accumulate(++v.begin(), v.end(), std::to_string(v[0]),
[](const std::string& a, int b){
return a + ", " + std::to_string(b);
});
这适用于C++17:
template<class...T>
std::string join(const std::string& sep, T&&...strings) {
if constexpr(sizeof...(T)) {
auto t = ((strings + sep) + ...);
return t.substr(0, t.size() - sep.size());
} else {
return "";
}
}
int main() {
std::cout << join(",", "apple", "orange", "banana") << std::endl;
std::cout << join(",") << std::endl;
}
它应该打印:
apple,orange,banana
C++字符串得到了有效的实现。
std::string s = s1 + s2 + s3;
这可能更快:
std::string str;
str.reserve(total_size_to_concat);
for (std::size_t i = 0; i < s.length(); i++)
{
str.append(s[i], s[i].length());
}
但这基本上就是编译器对operator+
和最小优化所做的,只是猜测要保留的大小
不要害羞。看看字符串的实现。:)
这里有另一个我觉得更方便使用的版本:
std::string join(std::initializer_list<std::string> initList, const std::string& separator = "\")
{
std::string s;
for(const auto& i : initList)
{
if(s.empty())
{
s = i;
}
else
{
s += separator + i;
}
}
return s;
}
你可以这样称呼它:
join({"C:", "Program Files", "..."});
如果你在项目中使用Qt,你可以直接使用QString的join
函数(QString Reference),它可以像python中预期的那样工作。一些例子:
QStringList strList;
qDebug() << strList.join(" and ");
结果:""
strList << "id = 1";
qDebug() << strList.join(" and ");
结果:"id = 1"
strList << "name = me";
qDebug() << strList.join(" and ");
结果:"id = 1 and name = me"
只是另一个简单的解决方案:
template<class T>
std::string str_join(const std::string& delim, const T& items)
{
std::string s;
for (const auto& item : items) {
if (!s.empty()) {
s += delim;
}
s += item;
}
return s;
}
对于那些不喜欢begin()
、end()
作为参数并且只喜欢整个容器的人。对于那些不喜欢字符串流而喜欢operator std::string() const
的人来说。
用法:
auto s1 = str_join(", ", std::vector<const char*>{"1","2","3"});
struct X
{
operator std::string() const
{
return "X";
}
};
auto s2 = str_join(":", std::vector<X>{{}, {}, {}});
应使用C++11及更高版本。
- 在std::thread中,joinable()然后join()线程安全吗
- join() 失败,如果在线程内部调用 io_context.run()
- std::future::get()或std::future::wait()是std::thread::join()的替
- c++17 std::thread join() : 没有这样的进程
- std::thread::join() 可以从非父线程调用吗?
- 使用 vector<thread> 和 .join() 未并行运行的多线程C++程序
- 为什么在线程销毁之前必须调用 join() 或 detach()
- thread.join() 的工作原理
- 有没有办法在C++中实现 Python 的 join()?
- 使用Boost :: Join合并多个阵列
- 寻找 std::join 行为的澄清
- 使用 Ranges-v3 视图::join保留双向性
- 在我调用join()之前,std ::线程运行
- 线程:join上是否存在具有synchronized with relationship的隐式内存障碍
- 线程已退出,代码为 1:Join() 和 Detach()
- QML DoubleValidator separator
- C++/pthread/join 错误消息的含义 "what(): Invalid argument"
- 当不调用thread.join()时,C 多线程异常
- boost - thread.join() halts the ui
- 有没有办法在C++中实现Python的"separator".join()的模拟?