Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何更改分隔符';什么位置?_C++_Iterator - Fatal编程技术网

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" ) );