In article <dnnTf.82$Ur4.4428@news.uswest.net>,
mmcnurlin@usfamily.net says...
[ ... ]
[color=blue]
> The following code produces a compiler error:
>
> #include "stdafx.h"
> #include <fstream>
> #include <iostream>
> #include <istream>
> #include <vector>
> #include <iterator>
>
> using namespace std;
>
> int main(int argc, char* argv[]) {
> ifstream file("num.txt", ios::in);
> int x;
> if(file) {
> istream_iterator<int, ptrdiff_t> i(file), eof;[/color]
An istream_iterator is normally created with one template
parameter. If you're reading structured data, you need to
define a structure of some sort, and then read in objects
of that type. At first glance, it looks like you're
trying to say you have a file of pairs of int's and
ptrdiff_t's, but storing a ptrdiff_t in a file is a bit
unusual, so I'm not sure whether that's what you intend
or not. Assuming it is, you'd do the job something like:
typedef std::pair<int, ptrdiff_t> f_type;
namespace std {
istream &operator>>(istream &is, f_type &p)
{
is >> p.first;
is >> p.second;
return is;
}
};
if (file) {
std::istream_iterator<f_type> i(file), eof;
A couple of notes: first of all, what we've added to
namespace std is a new specialization of an existing
operator for a user-defined type -- which is nearly the
only time we're allowed to add something to the std
namespace.
This code is being added TO namespace std, so we don't
have to specify 'std' on names -- the current namespace
is always searched for names anyway.
[color=blue]
> // copyio.cpp : Defines the entry point for the console application.
> //Taken from "STL for C++ programmers" by Leen Ammeral.
> // I abandoned it because it line 22 and line 25 didn't compile[/color]
When posting something like this, it's extremely helpful
if you add a comment on the line(s) you're talking about.
It's quite difficult to guess where to start counting
lines from...
[color=blue]
> using namespace std;
>
> int main(int argc, char* argv[])
> {
> vector<int> a;
> ifstream file("example.txt", 0);
> if(!file) {
> cout << "Cannot open file example.txt" << endl;
> return 1;
> }
> copy(istream_iterator<int, ptrdiff_t> (file),
> istream_iterator<int, ptrdiff_t>(),
> inserter(a,a.begin()));[/color]
You have the same basic problem here as above -- an
istream_iterator takes only one template parameter. As
above, it's not at all clear what you intend the
ptrdiff_t to mean. Since I showed code using it above,
this time I'll show code that just reads ints -- since
you're putting the result into a vector of int, that's
probably what you really want (in both cases).
When you're putting things into a vector, you _usually_
want to use back_inserter (though it doesn't matter a
whole lot).
copy(istream_iterator<int>(file),
istream_iterator<int>(),
back_inserter(a, a.begin()));
copy(a.begin(),a.end(),
ostream_iterator<int>(cout," "));
cout <<endl;
Also note that if you intend to copy from an input file
to an output file, without doing any processing in
between, you can skip using the vector in between, and
copy directly from one stream to the other:
copy(istream_iterator<int>(file),
istream_iterator<int>(),
ostream_iterator<int>(cout, " "));
If you want to do processing like sorting that works with
the entire data set, you may need to copy to a container.
If you want to do something on the order of line-based
filtering, you can often use std::transform instead of
std::copy, and (again) do the filtering on the way
through, without creating an intermediate copy of all the
data.
--
Later,
Jerry.
The universe is a figment of its own imagination.