By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,963 Members | 1,714 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,963 IT Pros & Developers. It's quick & easy.

std::istreambuf_iterator

P: n/a
Hi,

This should be a simple problem, but I can't seem to figure it out.
Maybe someone can help?

I have a file containing data each line has about 6 entries (numbers)
space delimited and each line has a new line character at the end of
the line. I'd like to read the file in one pass, so I am trying to use
std::istreambuf_iterator as follows (where inputFile is an ifstream):

std::vector<std::string>
data( std::istreambuf_iterator<std::string>(inputFile) ,
std::istreambuf_iterator<std::string>())

The problem I am facing is that I cannot then iterate over vector of
strings in the usual manner;

std::vector<std::string>::iterator(data.begin());
OR
std::vector<std::string>::iterator(data->begin());

I keep getting compilation errors:

error: request for member `begin' in `data', which is of non-aggregate
type `std::vector<std::string, std::allocator<std::string ()
(std::istreambuf_iterator<std::string, std::char_traits<std::string>
>, std::istreambuf_iterator<std::string, std::char_traits<std::string>
(*)())'
I must be missing something completely. I'd greatly appreciate some
help. Thanks.

Aug 9 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a

ahmadcorp <ma*****@gmail.comwrote in message...
Hi,
This should be a simple problem, but I can't seem to figure it out.
Maybe someone can help?

I have a file containing data each line has about 6 entries (numbers)
space delimited and each line has a new line character at the end of
the line. I'd like to read the file in one pass, so I am trying to use
std::istreambuf_iterator as follows (where inputFile is an ifstream):

std::vector<std::string>
data( std::istreambuf_iterator<std::string>(inputFile) ,
std::istreambuf_iterator<std::string>())

The problem I am facing is that I cannot then iterate over vector of
strings in the usual manner;

std::vector<std::string>::iterator(data.begin());
OR
std::vector<std::string>::iterator(data->begin());

I keep getting compilation errors:

error: request for member `begin' in `data', which is of non-aggregate
type `std::vector<std::string, std::allocator<std::string ()
(std::istreambuf_iterator<std::string, std::char_traits<std::string>
, std::istreambuf_iterator<std::string, std::char_traits<std::string>
(*)())'

I must be missing something completely. I'd greatly appreciate some
help. Thanks.
I prefer:

std::vector<std::stringdata;
for( std::string line; std::getline( inputFile, line ); /*m t*/ ){
data.push_back( line );
}

Try this (note the '.rdbuf()' addition):

std::vector<std::stringdata(
std::istreambuf_iterator<std::string>( inputFile.rdbuf() ),
std::istreambuf_iterator<std::string>()
);

Does it compile now?

--
Bob R
POVrookie
Aug 9 '07 #2

P: n/a

ahmadcorp <ma*****@gmail.comwrote in message...
Hi,

This should be a simple problem, but I can't seem to figure it out.
Maybe someone can help?

I have a file containing data each line has about 6 entries (numbers)
space delimited and each line has a new line character at the end of
the line. I'd like to read the file in one pass, so I am trying to use
std::istreambuf_iterator as follows (where inputFile is an ifstream):

std::vector<std::string>
data( std::istreambuf_iterator<std::string>(inputFile) ,
std::istreambuf_iterator<std::string>())

The problem I am facing is that I cannot then iterate over vector of
strings in the usual manner;

std::vector<std::string>::iterator(data.begin());
OR
std::vector<std::string>::iterator(data->begin());

I keep getting compilation errors:

error: request for member `begin' in `data', which is of non-aggregate
type `std::vector<std::string, std::allocator<std::string ()
(std::istreambuf_iterator<std::string, std::char_traits<std::string>
, std::istreambuf_iterator<std::string, std::char_traits<std::string>
(*)())'

I must be missing something completely. I'd greatly appreciate some
help. Thanks.
I prefer:

std::vector<std::stringdata;

// ------- lines
for( std::string line; std::getline( inputFile, line ); /*m t*/ ){
data.push_back( line );
}
// -------

// ------- words
std::copy(
std::istream_iterator<std::string>( inputFile ),
std::istream_iterator<std::string>(),
std::back_inserter( data ) );
// -------

std::copy( data.begin(), data.end(),
std::ostream_iterator<std::string>( std::cout, "\n" ) );

[from my (old) docs]
// -------
The istream and ostream classes are meant to handle conversion between
objects in your program and their textual representation.

By contrast, the underlying streambuf class is for transferring raw bytes
between your program, and input sources or output sinks. Different streambuf
subclasses connect to different kinds of sources and sinks.
// -------

std::vector<unsigned charImage( // or <char>
std::istreambuf_iterator<char>( inputFile.rdbuf() ),
std::istreambuf_iterator<char>()
);

--
Bob R
POVrookie
Aug 9 '07 #3

P: n/a
On Aug 9, 6:50 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
ahmadcorp <manz...@gmail.comwrote in message...
Hi,
This should be a simple problem, but I can't seem to figure it out.
Maybe someone can help?
I have a file containing data each line has about 6 entries (numbers)
space delimited and each line has a new line character at the end of
the line. I'd like to read the file in one pass, so I am trying to use
std::istreambuf_iterator as follows (where inputFile is an ifstream):
std::vector<std::string>
data( std::istreambuf_iterator<std::string>(inputFile) ,
std::istreambuf_iterator<std::string>())
The problem I am facing is that I cannot then iterate over vector of
strings in the usual manner;
std::vector<std::string>::iterator(data.begin());
OR
std::vector<std::string>::iterator(data->begin());
I keep getting compilation errors:
error: request for member `begin' in `data', which is of non-aggregate
type `std::vector<std::string, std::allocator<std::string ()
(std::istreambuf_iterator<std::string, std::char_traits<std::string>
>, std::istreambuf_iterator<std::string, std::char_traits<std::string>
(*)())'
I must be missing something completely. I'd greatly appreciate some
help. Thanks.

I prefer:

std::vector<std::stringdata;

// ------- lines
for( std::string line; std::getline( inputFile, line ); /*m t*/ ){
data.push_back( line );
}
// -------

// ------- words
std::copy(
std::istream_iterator<std::string>( inputFile ),
std::istream_iterator<std::string>(),
std::back_inserter( data ) );
// -------

std::copy( data.begin(), data.end(),
std::ostream_iterator<std::string>( std::cout, "\n" ) );

[from my (old) docs]
// -------
The istream and ostream classes are meant to handle conversion between
objects in your program and their textual representation.

By contrast, the underlying streambuf class is for transferring raw bytes
between your program, and input sources or output sinks. Different streambuf
subclasses connect to different kinds of sources and sinks.
// -------

std::vector<unsigned charImage( // or <char>
std::istreambuf_iterator<char>( inputFile.rdbuf() ),
std::istreambuf_iterator<char>()
);

--
Bob R
POVrookie

Hi,

Thanks for the reply. Works like a charm.

Decided to memory map the file and then process internally. Seems to
be a lot faster than reading file line by line.

Maz.

Aug 10 '07 #4

P: n/a
Hi!

ahmadcorp schrieb:
std::vector<std::string>
data( std::istreambuf_iterator<std::string>(inputFile) ,
std::istreambuf_iterator<std::string>())
[snip]
error: request for member `begin' in `data', which is of non-aggregate
type `std::vector<std::string, std::allocator<std::string ()
(std::istreambuf_iterator<std::string, std::char_traits<std::string>
>, std::istreambuf_iterator<std::string, std::char_traits<std::string>
(*)())'
The "data" variable is not a variable at all. That is because the
declaration of "data" can be interpreted as a function declaration. The
compiler is required to prefer that. Thus "data" is a function. And
functions don't have "begin()" and "end()".

It can be solved by having extra variables:

void foo(std::istream& file)
{
using namespace std;
istream_iterator<stringfirst(file), last;
vector<stringdata(first, last);

data.begin(); //works
}
HTH, Frank
Aug 10 '07 #5

P: n/a
On Aug 9, 1:57 pm, ahmadcorp <manz...@gmail.comwrote:
This should be a simple problem, but I can't seem to figure it out.
Maybe someone can help?
It's a very simple problem, once you've seen it. On the other
hand, I don't know of anyone who hasn't hit it once or twice.
I have a file containing data each line has about 6 entries (numbers)
space delimited and each line has a new line character at the end of
the line. I'd like to read the file in one pass, so I am trying to use
std::istreambuf_iterator as follows (where inputFile is an ifstream):
std::vector<std::string>
data( std::istreambuf_iterator<std::string>(inputFile) ,
std::istreambuf_iterator<std::string>())
Attention: here, you are not defining a variable, but declaring
a function. (Isn't C++ declaration syntax horrible.) You need
to do something so that at least one of the "arguments" can't be
interpreted as a parameter declaration; an extra pair of
parentheses will do the trick:

std::vector< std::string >
data(
(std::istreambuf_iterator< std::string >( inputFile )),
(std::istreambuf_iterator< std::string >()) ) ;

(Formally, it's sufficient to add the parentheses to just one of
the arguments, but I like orthogonality.)

--
James Kanze (GABI Software) email:james.ka...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Aug 11 '07 #6

P: n/a

James Kanze <ja*********@gmail.comwrote in message...

/* """ quote
Attention: here, you are not defining a variable, but declaring
a function. (Isn't C++ declaration syntax horrible.) You need
to do something so that at least one of the "arguments" can't be
interpreted as a parameter declaration; an extra pair of
parentheses will do the trick:

std::vector< std::string >
data(
(std::istreambuf_iterator< std::string >( inputFile )),
(std::istreambuf_iterator< std::string >()) ) ;

(Formally, it's sufficient to add the parentheses to just one of
the arguments, but I like orthogonality.)
""" */

Did that compile for you ( using std::string in istreambuf_iterator!! )?
(which compiler?)

--
Bob R
POVrookie
Aug 11 '07 #7

P: n/a
On Aug 11, 6:16 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
James Kanze <james.ka...@gmail.comwrote in message...
Attention: here, you are not defining a variable, but declaring
a function. (Isn't C++ declaration syntax horrible.) You need
to do something so that at least one of the "arguments" can't be
interpreted as a parameter declaration; an extra pair of
parentheses will do the trick:
std::vector< std::string >
data(
(std::istreambuf_iterator< std::string >( inputFile )),
(std::istreambuf_iterator< std::string >()) ) ;
(Formally, it's sufficient to add the parentheses to just one of
the arguments, but I like orthogonality.)
Did that compile for you ( using std::string in
istreambuf_iterator!! )? (which compiler?)
You're right, I didn't try it:-). You'd need
std::istream_iterator for std::string. Don't know what I was
thinking of.

--
James Kanze (GABI Software) email:james.ka...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Aug 11 '07 #8

P: n/a

James Kanze <ja*********@gmail.comwrote in message...

/* """
On Aug 11, 6:16 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
James Kanze <james.ka...@gmail.comwrote in message...
std::vector< std::string data(
(std::istreambuf_iterator< std::string >( inputFile )),
(std::istreambuf_iterator< std::string >()) ) ;
(Formally, it's sufficient to add the parentheses to just one of
the arguments, but I like orthogonality.)
Did that compile for you ( using std::string in
istreambuf_iterator!! )? (which compiler?)
You're right, I didn't try it:-). You'd need
std::istream_iterator for std::string.
""" */
Don't know what I was thinking of.
Probably that thread a while back. But, that was using type 'char'.

// ref: std::ifstream PicIn( ...., '::in | '::binary );

std::vector<unsigned charImage(
std::istreambuf_iterator<char>( PicIn.rdbuf() ),
std::istreambuf_iterator<char>()
);

The code you showed was the *first* thing I tried. <G>
[ so, my 'single-brain-cell' brain *does* retain some things. :-} ]

--
Bob R
POVrookie
Aug 11 '07 #9

P: n/a
On Aug 11, 11:51 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
James Kanze <james.ka...@gmail.comwrote in message...
On Aug 11, 6:16 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
James Kanze <james.ka...@gmail.comwrote in message...
std::vector< std::string data(
(std::istreambuf_iterator< std::string >( inputFile )),
(std::istreambuf_iterator< std::string >()) ) ;
(Formally, it's sufficient to add the parentheses to just one of
the arguments, but I like orthogonality.)
Did that compile for you ( using std::string in
istreambuf_iterator!! )? (which compiler?)
You're right, I didn't try it:-). You'd need
std::istream_iterator for std::string.
Don't know what I was thinking of.
Probably that thread a while back. But, that was using type 'char'.
Not really. I was basing my response on the original posting,
plus the error message he got. The error message was due to his
declaring a function, not a variable. (And of course, declaring
std::istreambuf_iterator< std::string as a parameter of a
function probably won't cause any errors from the compiler,
since using a class template as a function parameter in a
declaration doesn't trigger instantiation.)
// ref: std::ifstream PicIn( ...., '::in | '::binary );
std::vector<unsigned charImage(
std::istreambuf_iterator<char>( PicIn.rdbuf() ),
std::istreambuf_iterator<char>()
);
The code you showed was the *first* thing I tried. <G>
Which, of course, would generate a different error message than
the one he got. So he really had two problems. The data
definition which is really a function declaration is so common
that I didn't think further, but that's not really an excuse for
posting an answer without having actually tried it. (Formally,
std::istreambuf_iterator< std::string is undefined behavior,
so you're not guaranteed a compiler error. But I'd be very
surprised if you didn't get one if you actually tried to use it.

--
James Kanze (GABI Software) email:james.ka...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Aug 12 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.