C++ 通过 copy() 输出
C++ Output via copy()
我正在使用 C++ 和 STL,我试图将双端队列复制到列表中并通过 copy() 和 ostream_iterator 打印列表。出于某种原因,除非我通过 front()、back() 或 at() 访问元素,否则不会打印我复制到的列表的内容。为什么前两次打印尝试失败:
#include <iostream>
#include <fstream>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
using namespace std;
void alterParticle(string&);
int main(){
string tmp_str;
deque<string> d;
list<string> l;
ifstream in("foo.txt");
if(!in.is_open()){
cout << "Error opening file" << endl;
return 1;
}
while(in){
getline(in,tmp_str);
d.push_back(tmp_str);
}
for_each(d.begin(),d.end(),alterParticle);
copy(d.begin(),d.end(),ostream_iterator<string>(cout,"\n"));
ostream_iterator<string> out(cout,"\n");
copy_if(d.begin(),d.end(),out,
[](const string& s){
if(s.find("fooparticle")!= string::npos)
return true;
return false;
});
copy_if(d.begin(),d.end(),l.begin(),
[](const string& s){
if(s.find("fooparticle")!= string::npos)
return true;
return false;
});
cout << "First try: " << endl;
for(string s : l)
cout << s << endl;
cout << "Second try: " << endl;
copy(l.begin(),l.end(),out);
cout << "Last try: " << l.front() << endl;
return 0;
}
void alterParticle(string& s){
int fpos = s.find("quark");
string rep_str{"quark"};
if(fpos != string::npos){
s.replace(s.find(rep_str),rep_str.length(),"fooparticle");
}
}
输出:
fooparticle 10 11.4
neutrino 7 20.5
electron 5 6.7
proton 8 9.5
fooparticle 10 11.4
First try:
Second try:
Last try: fooparticle 10 11.4
编辑:
只是为了更容易理解为什么这对提出相同问题的人不起作用,这里是 copy_if() 的语义。它很清楚地表明它不会扩展容器:
template <class InputIterator, class OutputIterator, class UnaryPredicate>
OutputIterator copy_if (InputIterator first, InputIterator last,
OutputIterator result, UnaryPredicate pred)
{
while (first!=last) {
if (pred(*first)) {
*result = *first;
++result;
}
++first;
}
return result;
}
copy
和 copy_if
不向 list
添加新元素,它们假定存在要复制到的现有元素。您的列表最初是空的,因此您正在写入列表的 begin() == end()
迭代器。这不会增加列表大小(这就是前两次尝试什么都不打印的原因),但是如果您访问(实际上不存在的)第一个列表成员,您可能会得到写在那里的结果。
不用说,分配给 end()
迭代器是未定义的行为。
您可以继续使用 copy
和朋友,如果您使用 insert_iterator
(you'd generally use back_inserter
),类似于您已经在使用的 ostream_iterator
。
我正在使用 C++ 和 STL,我试图将双端队列复制到列表中并通过 copy() 和 ostream_iterator 打印列表。出于某种原因,除非我通过 front()、back() 或 at() 访问元素,否则不会打印我复制到的列表的内容。为什么前两次打印尝试失败:
#include <iostream>
#include <fstream>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
using namespace std;
void alterParticle(string&);
int main(){
string tmp_str;
deque<string> d;
list<string> l;
ifstream in("foo.txt");
if(!in.is_open()){
cout << "Error opening file" << endl;
return 1;
}
while(in){
getline(in,tmp_str);
d.push_back(tmp_str);
}
for_each(d.begin(),d.end(),alterParticle);
copy(d.begin(),d.end(),ostream_iterator<string>(cout,"\n"));
ostream_iterator<string> out(cout,"\n");
copy_if(d.begin(),d.end(),out,
[](const string& s){
if(s.find("fooparticle")!= string::npos)
return true;
return false;
});
copy_if(d.begin(),d.end(),l.begin(),
[](const string& s){
if(s.find("fooparticle")!= string::npos)
return true;
return false;
});
cout << "First try: " << endl;
for(string s : l)
cout << s << endl;
cout << "Second try: " << endl;
copy(l.begin(),l.end(),out);
cout << "Last try: " << l.front() << endl;
return 0;
}
void alterParticle(string& s){
int fpos = s.find("quark");
string rep_str{"quark"};
if(fpos != string::npos){
s.replace(s.find(rep_str),rep_str.length(),"fooparticle");
}
}
输出:
fooparticle 10 11.4
neutrino 7 20.5
electron 5 6.7
proton 8 9.5
fooparticle 10 11.4
First try:
Second try:
Last try: fooparticle 10 11.4
编辑:
只是为了更容易理解为什么这对提出相同问题的人不起作用,这里是 copy_if() 的语义。它很清楚地表明它不会扩展容器:
template <class InputIterator, class OutputIterator, class UnaryPredicate>
OutputIterator copy_if (InputIterator first, InputIterator last,
OutputIterator result, UnaryPredicate pred)
{
while (first!=last) {
if (pred(*first)) {
*result = *first;
++result;
}
++first;
}
return result;
}
copy
和 copy_if
不向 list
添加新元素,它们假定存在要复制到的现有元素。您的列表最初是空的,因此您正在写入列表的 begin() == end()
迭代器。这不会增加列表大小(这就是前两次尝试什么都不打印的原因),但是如果您访问(实际上不存在的)第一个列表成员,您可能会得到写在那里的结果。
不用说,分配给 end()
迭代器是未定义的行为。
您可以继续使用 copy
和朋友,如果您使用 insert_iterator
(you'd generally use back_inserter
),类似于您已经在使用的 ostream_iterator
。