我知道如何用其他语言来做这件事,而不是C++,我不得不在这里使用它.
我有一组字符串,我打印到列表中,并且每个字符串之间需要逗号,但不是逗号.例如,在java中,我会使用stringbuilder,并在构建字符串后删除逗号.我如何用C++做到这一点?
auto iter = keywords.begin();
for (iter; iter != keywords.end( ); iter++ )
{
out << *iter << ", ";
}
out << endl;
Run Code Online (Sandbox Code Playgroud)
我最初尝试插入此块来执行此操作(在此处移动逗号打印)
if (iter++ != keywords.end())
out << ", ";
iter--;
Run Code Online (Sandbox Code Playgroud)
我讨厌小东西把我绊倒的时候.
编辑:谢谢大家.这就是我在这里发布这样的东西的原因.这么多好的答案,并以不同的方式解决.经过一个学期的Java和汇编(不同的类),不得不在4天内完成一个C++项目,这让我陷入了困境.我不仅得到了答案,还有机会思考解决这类问题的不同方法.真棒.
Jer*_*fin 52
使用infix_iterator:
// infix_iterator.h
//
// Lifted from Jerry Coffin's 's prefix_ostream_iterator
#if !defined(INFIX_ITERATOR_H_)
#define INFIX_ITERATOR_H_
#include <ostream>
#include <iterator>
template <class T,
class charT=char,
class traits=std::char_traits<charT> >
class infix_ostream_iterator :
public std::iterator<std::output_iterator_tag,void,void,void,void>
{
std::basic_ostream<charT,traits> *os;
charT const* delimiter;
bool first_elem;
public:
typedef charT char_type;
typedef traits traits_type;
typedef std::basic_ostream<charT,traits> ostream_type;
infix_ostream_iterator(ostream_type& s)
: os(&s),delimiter(0), first_elem(true)
{}
infix_ostream_iterator(ostream_type& s, charT const *d)
: os(&s),delimiter(d), first_elem(true)
{}
infix_ostream_iterator<T,charT,traits>& operator=(T const &item)
{
// Here's the only real change from ostream_iterator:
// Normally, the '*os << item;' would come before the 'if'.
if (!first_elem && delimiter != 0)
*os << delimiter;
*os << item;
first_elem = false;
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator*() {
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator++() {
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator++(int) {
return *this;
}
};
#endif
Run Code Online (Sandbox Code Playgroud)
用法如下:
#include "infix_iterator.h"
// ...
std::copy(keywords.begin(), keywords.end(), infix_iterator(out, ","));
Run Code Online (Sandbox Code Playgroud)
Tem*_*Rex 29
在即将推出的实验性C++ 17就绪编译器中,您可以使用std::experimental::ostream_joiner
:
#include <algorithm>
#include <experimental/iterator>
#include <iostream>
#include <iterator>
int main()
{
int i[] = {1, 2, 3, 4, 5};
std::copy(std::begin(i),
std::end(i),
std::experimental::make_ostream_joiner(std::cout, ", "));
}
Run Code Online (Sandbox Code Playgroud)
使用GCC 6.0 SVN和Clang 3.9 SVN的实例
Jam*_*ong 25
因为每个人都决定用while循环来做这个,所以我将给出一个for循环的例子.
for (iter = keywords.begin(); iter != keywords.end(); iter++) {
if (iter != keywords.begin()) cout << ", ";
cout << *iter;
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*sop 18
假设一个模糊的正常输出流,那么写一个空字符串确实无效:
const char *padding = "";
for (auto iter = keywords.begin(); iter != keywords.end(); ++iter) {
out << padding << *iter;
padding = ", "
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*k B 16
一种常见的方法是在循环之前打印第一个项目,并仅循环其余项目,在每个剩余项目之前预打印逗号.
或者,您应该能够创建自己的流来维护行的当前状态(在endl之前)并将逗号放在适当的位置.
编辑:您也可以使用TED建议的中间测试循环它将是这样的:
if(!keywords.empty())
{
auto iter = keywords.begin();
while(true)
{
out << *iter;
++iter;
if(iter == keywords.end())
{
break;
}
else
{
out << ", ";
}
}
}
Run Code Online (Sandbox Code Playgroud)
我首先提到了"在循环之前打印第一项"方法,因为它保持循环体非常简单,但任何方法都可以正常工作.
像这样的东西?
while (iter != keywords.end())
{
out << *iter;
iter++;
if (iter != keywords.end()) cout << ", ";
}
Run Code Online (Sandbox Code Playgroud)
有许多聪明的解决方案,并且有太多的解决方案使代码无法超越拯救的希望而不让编译器完成其工作.
在明显的解决方案,是特殊情况下的第一次迭代:
bool first = true;
for (auto const& e: sequence) {
if (first) { first = false; } else { out << ", "; }
out << e;
}
Run Code Online (Sandbox Code Playgroud)
这是一个死的简单模式:
else
块和循环体可以包含任意语句.它可能不是绝对最有效的代码,但单个预测分支的潜在性能损失很可能被巨大的庞然大物所掩盖std::ostream::operator<<
.
我使用分隔符(使用任何语言)的典型方法是使用经过中期测试的循环.C++代码将是:
for (;;) {
std::cout << *iter;
if (++iter == keywords.end()) break;
std::cout << ",";
}
Run Code Online (Sandbox Code Playgroud)
(注意:if
如果关键字可能为空,则需要在循环之前进行额外检查)
显示的大多数其他解决方案最终会在每次循环迭代时执行完整的额外测试.你正在做I/O,所以这个时间不是一个大问题,但它会冒犯我的感情.
在python中我们只写:
print ", ".join(keywords)
Run Code Online (Sandbox Code Playgroud)
那么为什么不:
template<class S, class V>
std::string
join(const S& sep, const V& v)
{
std::ostringstream oss;
if (!v.empty()) {
typename V::const_iterator it = v.begin();
oss << *it++;
for (typename V::const_iterator e = v.end(); it != e; ++it)
oss << sep << *it;
}
return oss.str();
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
cout << join(", ", keywords) << endl;
Run Code Online (Sandbox Code Playgroud)
与上面的python示例不同,the " "
is a string and the must keywords
be an iterable of strings,在这个C++示例中,分隔符keywords
可以是任何可流式传输的,例如
cout << join('\n', keywords) << endl;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
23470 次 |
最近记录: |