Aud*_*oid 33 c++ csv string boost stringstream
可能重复:
请勿在最后一个数字后打印空格
使用逗号C++打印列表
#include <vector>
#include <iostream>
#include <sstream>
#include <boost/foreach.hpp>
using namespace std;
int main()
{
vector<int> VecInts;
VecInts.push_back(1);
VecInts.push_back(2);
VecInts.push_back(3);
VecInts.push_back(4);
VecInts.push_back(5);
stringstream ss;
BOOST_FOREACH(int i, VecInts)
{
ss << i << ",";
}
cout << ss.str();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这打印出来:1,2,3,4,5,
但是我想要:1,2,3,4,5
我怎样才能以优雅的方式实现这一目标?
我看到我对"优雅"的含义有些困惑:例如,我的循环中没有减慢"if-clause"的速度.想象一下向量中的100.000个条目!如果这就是你要提供的全部内容,我宁愿在完成循环后删除最后一个逗号.
mrm*_*mrm 32
这个怎么样:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
#include <sstream>
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
std::ostringstream ss;
if(!v.empty()) {
std::copy(v.begin(), std::prev(v.end()), std::ostream_iterator<int>(ss, ", "));
ss << v.back();
}
std::cout << ss.str() << "\n";
}
Run Code Online (Sandbox Code Playgroud)
无需添加额外的变量,甚至不依赖于提升!实际上,除了"循环中没有额外的变量"要求之外,可以说甚至没有循环:)
Mat*_* M. 15
在最后检测之前总是很棘手,检测第一个很容易.
bool first = true;
stringstream ss;
BOOST_FOREACH(int i, VecInts)
{
if (!first) { ss << ","; }
first = false;
ss << i;
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*edy 10
使用来自提升精神的业力 - 以快速而闻名.
#include <iostream>
#include <vector>
#include <boost/spirit/include/karma.hpp>
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
using namespace boost::spirit::karma;
std::cout << format(int_ % ',', v) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
尝试:
if (ss.tellp ())
{
ss << ",";
}
ss << i;
Run Code Online (Sandbox Code Playgroud)
或者,如果"if"让你担心:
char *comma = "";
BOOST_FOREACH(int i, VecInts)
{
ss << comma << i;
comma = ",";
}
Run Code Online (Sandbox Code Playgroud)
就个人而言,我喜欢一种不会导致潜在内存分配的解决方案(因为字符串变得比需要的大).由于分支目标缓冲,循环体内的额外if应该是易处理的,但我会这样做:
#include <vector>
#include <iostream>
int main () {
using std::cout;
typedef std::vector<int>::iterator iterator;
std::vector<int> ints;
ints.push_back(5);
ints.push_back(1);
ints.push_back(4);
ints.push_back(2);
ints.push_back(3);
if (!ints.empty()) {
iterator it = ints.begin();
const iterator end = ints.end();
cout << *it;
for (++it; it!=end; ++it) {
cout << ", " << *it;
}
cout << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
或者,BYORA(带上您自己的可重用算法):
// Follow the signature of std::getline. Allows us to stay completely
// type agnostic.
template <typename Stream, typename Iter, typename Infix>
inline Stream& infix (Stream &os, Iter from, Iter to, Infix infix_) {
if (from == to) return os;
os << *from;
for (++from; from!=to; ++from) {
os << infix_ << *from;
}
return os;
}
template <typename Stream, typename Iter>
inline Stream& comma_seperated (Stream &os, Iter from, Iter to) {
return infix (os, from, to, ", ");
}
Run Code Online (Sandbox Code Playgroud)
以便
...
comma_seperated(cout, ints.begin(), ints.end()) << std::endl;
infix(cout, ints.begin(), ints.end(), "-") << std::endl;
infix(cout, ints.begin(), ints.end(), "> <") << std::endl;
...
Run Code Online (Sandbox Code Playgroud)
输出:
5, 1, 4, 2, 3
5-1-4-2-3
5> <1> <4> <2> <3
Run Code Online (Sandbox Code Playgroud)
整洁的事情是它适用于每个输出流,任何具有前向迭代器的容器,任何中缀,以及任何中缀类型(有趣的是,例如当你使用宽字符串时).