C++ 如何更改分隔符';什么位置?
这个例子:C++ 如何更改分隔符';什么位置?,c++,iterator,C++,Iterator,这个例子: #include <iostream> #include <iterator> #include <algorithm> int main() { int v[] = { 1, 2, 3 }; std::copy( &v[0], &v[3], std::ostream_iterator< int >( std::cout, "\n " ) ); } 是否有办法更改示例以使其生成下一个输出 1
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int v[] = { 1, 2, 3 };
std::copy( &v[0], &v[3], std::ostream_iterator< int >( std::cout, "\n " ) );
}
是否有办法更改示例以使其生成下一个输出
1
2
3
PS我知道我可以使用for循环,但我对使用算法和迭代器的解决方案感兴趣。在
std::copy
之前输出一个空格如果你想使用C++11,你可以使用lambda
e、 g像这样:
int v[] = { 1, 2, 3};
std::for_each( &v[0], &v[3], [](int i){ std::cout << " " << i << "\n";} );
intv[]={1,2,3};
std::for_each(&v[0],&v[3],](inti){std::cout使用std::cout不,不是真的。ostream_迭代器
不是这样配置的
因此,您必须使用其他答案中的空格前“变通方法”,并手动切掉最后一行
BTW严格来说,&v[3]
调用未定义的行为,因为子表达式v[3]
中存在隐式的取消引用。首选&v[0]+3
(或者只是v+3
)-“拥有”指向数组末尾的指针是可以的,只要它没有取消引用
您可以制作自己的ostream\u迭代器
,如下例所示
是的,它很冗长;但是,您也可以根据您不断变化的需求随意更改它:
#include <iostream>
#include <iterator>
#include <algorithm>
template <class T, class charT = char, class traits = std::char_traits<charT> >
struct ostream_iterator_x
: std::iterator<std::output_iterator_tag, void, void, void, void> {
typedef charT char_type;
typedef traits traits_type;
typedef std::basic_ostream<charT,traits> ostream_type;
ostream_iterator_x(ostream_type& s, const charT* pre = 0, const charT* post = 0)
: s(s)
, pre(pre)
, post(post) {};
ostream_iterator_x(const ostream_iterator_x& x)
: s(x.s)
, pre(x.pre)
, post(x.post) {};
~ostream_iterator_x() {}
ostream_iterator_x& operator=(const T& value) {
if (pre != 0) s << pre;
s << value;
if (post != 0) s << post;
return *this;
}
ostream_iterator_x& operator*() { return *this; }
ostream_iterator_x& operator++() { return *this; }
ostream_iterator_x& operator++(int) { return *this; }
private:
ostream_type& s;
const charT* pre;
const charT* post;
};
int main()
{
int v[] = { 1, 2, 3 };
std::copy(v, v+3, ostream_iterator_x<int>(std::cout, " ", "\n"));
}
// Output:
// 1
// 2
// 3
#包括
#包括
#include使用std::ostream\u迭代器(IMHO,应该有
是的,但它不在那里。)如果你不介意写一个额外的小字
功能或类别,
您可以使用std::transform
,例如:
struct FormatString
{
std::string operator()( std::string const& original ) const
{
return ' ' + original + '\n';
}
};
// ...
std::transform(
v.begin(), v.end(),
std::ostream_iterator<std::string>( std::cout ),
FormatString() );
我发现我经常使用它。(我还发现使用std::transform
更多。)
因为我输出的是一个
转换。)这个问题中没有C++11的问题。@Tomalak我使用的是g++4.3(它对C++11的支持非常有限),因此我创建了一个C++03示例。但是如果你能提供一个C++11解决方案,那也可以。(实际上,我对C++11解决方案更感兴趣)@iammilind Right。修复了它。我创建了一个数组中包含5个元素的示例,但我认为3个元素就足够了:)在ostream_迭代器的参数中:“\n”之后的额外空格是故意的吗?在这种情况下,你得到了你想要的。@Andre:问题是在第一行之前也添加一个空格。阅读文章的最后一行:我认为这绝对不是他想要的。@psycho:我认为这是肯定的。@Tomalak:在po阅读st title和最后一行,我真的不这么认为。我认为他完全能够产生这样一个简单的输出,问题似乎更多的是关于std::ostream_迭代器的使用。
。这个解决方案只是一个变通办法,就像@mkaes答案一样。但我不会激动,让他回答。@psycho:如果他能够产生“这样一个简单的输出”,那么他就不会问“有没有办法改变示例,使其产生[那个]输出?”@Tomalak:我想你是对的,问题不在于它应该是什么。而是你最后的答案(关于ostream_迭代器是可配置的)在我看来,它更适合这篇文章。@Tomalak:程序完全按照op的要求执行。我引用了这个问题。有没有办法改变示例以使其产生下一个输出?我的代码片段就是这样做的。为了澄清,在计算函数参数时,这只是将一个空间流到std::cout
(即在复制之前,
);它没有通过std::cout…但它看起来比std::cout要好得多@Nawaz:我觉得这是一个重要的澄清,对于那些可能偶然发现这个答案但还不熟悉这个事实的人来说。@Nawaz:你不是刚刚写过&v[3]
是UB吗?:)@托马拉克:这只是从原来的问题中复制粘贴,除了stc::cout
,没有看到他的代码的其他部分。无论如何,我建议他如何避免UB。好主意!简单有效。(今天早上已经投票通过,但应该再投票一次)@心理医生:呵呵,谢谢:)事后看来,我认为詹姆斯用std::transform
的方法更有意义。是的,我刚刚看到了。对于这种情况,是的,非常适合,但我通常更喜欢一种更一般而不是更具体的解决方案……所以两者对我来说都很有价值。
1
2
3
#include <iostream>
#include <iterator>
#include <algorithm>
template <class T, class charT = char, class traits = std::char_traits<charT> >
struct ostream_iterator_x
: std::iterator<std::output_iterator_tag, void, void, void, void> {
typedef charT char_type;
typedef traits traits_type;
typedef std::basic_ostream<charT,traits> ostream_type;
ostream_iterator_x(ostream_type& s, const charT* pre = 0, const charT* post = 0)
: s(s)
, pre(pre)
, post(post) {};
ostream_iterator_x(const ostream_iterator_x& x)
: s(x.s)
, pre(x.pre)
, post(x.post) {};
~ostream_iterator_x() {}
ostream_iterator_x& operator=(const T& value) {
if (pre != 0) s << pre;
s << value;
if (post != 0) s << post;
return *this;
}
ostream_iterator_x& operator*() { return *this; }
ostream_iterator_x& operator++() { return *this; }
ostream_iterator_x& operator++(int) { return *this; }
private:
ostream_type& s;
const charT* pre;
const charT* post;
};
int main()
{
int v[] = { 1, 2, 3 };
std::copy(v, v+3, ostream_iterator_x<int>(std::cout, " ", "\n"));
}
// Output:
// 1
// 2
// 3
struct FormatString
{
std::string operator()( std::string const& original ) const
{
return ' ' + original + '\n';
}
};
// ...
std::transform(
v.begin(), v.end(),
std::ostream_iterator<std::string>( std::cout ),
FormatString() );
std::transform(
v.begin(), v.end(),
std::ostream_iterator<std::string>( std::cout ),
PatsubstTransformer( "%", " %\n" ) );