Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > std::vector::reserve and std::ifstream::read

Reply
Thread Tools

std::vector::reserve and std::ifstream::read

 
 
mathieu
Guest
Posts: n/a
 
      05-24-2011
Dear all,

I do not understand how to use the STL vector class with the
ifstream class. I would like to reserve a chunk of memory (no
initialization is required) and fill it with values from a file. As
far as I understand vector::reserve requires a subsequent call to
push_back or insert. However I do not see how I can do this in the
following example:


#include <fstream>
#include <vector>

int main(int argc, char *argv[])
{
const char *filename = argv[1];
std::ifstream is( filename );
const size_t l = 512;
std::vector<char> v;
v.reserve( l ); // need push_back or insert
is.read( &v[0], l ); // ?

return 0;
}


thanks for your help !
 
Reply With Quote
 
 
 
 
gwowen
Guest
Posts: n/a
 
      05-24-2011
On May 24, 9:58*am, mathieu <(E-Mail Removed)> wrote:
> Dear all,
>
> * I do not understand how to use the STL vector class with the
> ifstream class. I would like to reserve a chunk of memory (no
> initialization is required) and fill it with values from a file. As
> far as I understand vector::reserve requires a subsequent call to
> push_back or insert. However I do not see how I can do this in the
> following example:
>
> #include <fstream>
> #include <vector>
>
> int main(int argc, char *argv[])
> {
> * const char *filename = argv[1];
> * std::ifstream is( filename );
> * const size_t l = 512;
> * std::vector<char> v;
> * v.reserve( l ); // need push_back or insert


If you reserve() space, you can't read or write to that space until
you also adjust the size (as push_back() will, or resize()). The
reserve() may well speed your code up.

char tmp;
is.read(&tmp,1);
v.push_back(tmp);

// the C++/STL like solution will use an istream_iterator and a
back_inserter
// I've got to say, I don't care for it...
vector<char> V;
copy(istream_iterator<char>(is), istream_iterator<char>(),
back_inserter(V));
 
Reply With Quote
 
 
 
 
Michael Doubez
Guest
Posts: n/a
 
      05-24-2011
On 24 mai, 11:16, gwowen <(E-Mail Removed)> wrote:
> On May 24, 9:58*am, mathieu <(E-Mail Removed)> wrote:
>
>
>
>
>
>
>
>
>
> > Dear all,

>
> > * I do not understand how to use the STL vector class with the
> > ifstream class. I would like to reserve a chunk of memory (no
> > initialization is required) and fill it with values from a file. As
> > far as I understand vector::reserve requires a subsequent call to
> > push_back or insert. However I do not see how I can do this in the
> > following example:

>
> > #include <fstream>
> > #include <vector>

>
> > int main(int argc, char *argv[])
> > {
> > * const char *filename = argv[1];
> > * std::ifstream is( filename );
> > * const size_t l = 512;
> > * std::vector<char> v;
> > * v.reserve( l ); // need push_back or insert

>
> If you reserve() space, you can't read or write to that space until
> you also adjust the size (as push_back() will, or resize()). *The
> reserve() may well speed your code up.
>
> char tmp;
> is.read(&tmp,1);
> v.push_back(tmp);
>
> // the C++/STL like solution will use an istream_iterator and a
> back_inserter
> // I've got to say, I don't care for it...
> vector<char> V;
> copy(istream_iterator<char>(is), istream_iterator<char>(),
> back_inserter(V));


Or simply:
v.assign(stream_iterator<char>(is), istream_iterator<char>());

--
Michael
 
Reply With Quote
 
mathieu
Guest
Posts: n/a
 
      05-24-2011
On May 24, 1:01*pm, Michael Doubez <(E-Mail Removed)> wrote:
> On 24 mai, 11:16, gwowen <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On May 24, 9:58*am, mathieu <(E-Mail Removed)> wrote:

>
> > > Dear all,

>
> > > * I do not understand how to use the STL vector class with the
> > > ifstream class. I would like to reserve a chunk of memory (no
> > > initialization is required) and fill it with values from a file. As
> > > far as I understand vector::reserve requires a subsequent call to
> > > push_back or insert. However I do not see how I can do this in the
> > > following example:

>
> > > #include <fstream>
> > > #include <vector>

>
> > > int main(int argc, char *argv[])
> > > {
> > > * const char *filename = argv[1];
> > > * std::ifstream is( filename );
> > > * const size_t l = 512;
> > > * std::vector<char> v;
> > > * v.reserve( l ); // need push_back or insert

>
> > If you reserve() space, you can't read or write to that space until
> > you also adjust the size (as push_back() will, or resize()). *The
> > reserve() may well speed your code up.

>
> > char tmp;
> > is.read(&tmp,1);
> > v.push_back(tmp);

>
> > // the C++/STL like solution will use an istream_iterator and a
> > back_inserter
> > // I've got to say, I don't care for it...
> > vector<char> V;
> > copy(istream_iterator<char>(is), istream_iterator<char>(),
> > back_inserter(V));

>
> Or simply:
> v.assign(stream_iterator<char>(is), istream_iterator<char>());


It does not work for me. istream_iterator does not implement +()
operator:

v.assign( std::istream_iterator<char>(is),
std::istream_iterator<char>(is)+l);

Thanks
 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      05-24-2011
Am 24.05.2011 13:51, schrieb mathieu:
> On May 24, 1:01 pm, Michael Doubez<(E-Mail Removed)> wrote:
>> On 24 mai, 11:16, gwowen<(E-Mail Removed)> wrote:
>>
>>
>>
>>
>>
>>> On May 24, 9:58 am, mathieu<(E-Mail Removed)> wrote:

>>
>>>> Dear all,

>>
>>>> I do not understand how to use the STL vector class with the
>>>> ifstream class. I would like to reserve a chunk of memory (no
>>>> initialization is required) and fill it with values from a file. As
>>>> far as I understand vector::reserve requires a subsequent call to
>>>> push_back or insert. However I do not see how I can do this in the
>>>> following example:

>>
>>>> #include<fstream>
>>>> #include<vector>

>>
>>>> int main(int argc, char *argv[])
>>>> {
>>>> const char *filename = argv[1];
>>>> std::ifstream is( filename );
>>>> const size_t l = 512;
>>>> std::vector<char> v;
>>>> v.reserve( l ); // need push_back or insert

>>
>>> If you reserve() space, you can't read or write to that space until
>>> you also adjust the size (as push_back() will, or resize()). The
>>> reserve() may well speed your code up.

>>
>>> char tmp;
>>> is.read(&tmp,1);
>>> v.push_back(tmp);

>>
>>> // the C++/STL like solution will use an istream_iterator and a
>>> back_inserter
>>> // I've got to say, I don't care for it...
>>> vector<char> V;
>>> copy(istream_iterator<char>(is), istream_iterator<char>(),
>>> back_inserter(V));

>>
>> Or simply:
>> v.assign(stream_iterator<char>(is), istream_iterator<char>());

>
> It does not work for me. istream_iterator does not implement +()
> operator:
>
> v.assign( std::istream_iterator<char>(is),
> std::istream_iterator<char>(is)+l);


You are not supposed to do +x on this.

istream_iterator<char>(is) is an iterator refering to the begin of the
stream while istream_iterator<char>() refers to the end of the stream,
just like c.begin() and c.end() for any container.
That pair of iterators reads from the stream until it hits the end of
the stream (like end of file).

If you want to read into a fixed buffer of std::vector:

std::ifstream is( filename );
const size_t size = 512;
std::vector<char> buffer(size);
is.read(&buffer[0], size);

Check for errors after this and use is.gcount() to get the number of
bytes read.

--
Thomas
 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      05-24-2011
On 24 mai, 13:51, mathieu <(E-Mail Removed)> wrote:
> On May 24, 1:01*pm, Michael Doubez <(E-Mail Removed)> wrote:
>
>
>
>
>
>
>
>
>
> > On 24 mai, 11:16, gwowen <(E-Mail Removed)> wrote:

>
> > > On May 24, 9:58*am, mathieu <(E-Mail Removed)> wrote:

>
> > > > Dear all,

>
> > > > * I do not understand how to use the STL vector class with the
> > > > ifstream class. I would like to reserve a chunk of memory (no
> > > > initialization is required) and fill it with values from a file. As
> > > > far as I understand vector::reserve requires a subsequent call to
> > > > push_back or insert. However I do not see how I can do this in the
> > > > following example:

>
> > > > #include <fstream>
> > > > #include <vector>

>
> > > > int main(int argc, char *argv[])
> > > > {
> > > > * const char *filename = argv[1];
> > > > * std::ifstream is( filename );
> > > > * const size_t l = 512;
> > > > * std::vector<char> v;
> > > > * v.reserve( l ); // need push_back or insert

>
> > > If you reserve() space, you can't read or write to that space until
> > > you also adjust the size (as push_back() will, or resize()). *The
> > > reserve() may well speed your code up.

>
> > > char tmp;
> > > is.read(&tmp,1);
> > > v.push_back(tmp);

>
> > > // the C++/STL like solution will use an istream_iterator and a
> > > back_inserter
> > > // I've got to say, I don't care for it...
> > > vector<char> V;
> > > copy(istream_iterator<char>(is), istream_iterator<char>(),
> > > back_inserter(V));

>
> > Or simply:
> > v.assign(stream_iterator<char>(is), istream_iterator<char>());

>
> It does not work for me. istream_iterator does not implement +()
> operator:


Yes, they are not random access input iterator.

>
> * v.assign( std::istream_iterator<char>(is),
> std::istream_iterator<char>(is)+l);


You want to read char by char ?

char c;

If you want formatted input then:
is>>c;
If you want unformatted input then:
is.get(c);

And you loop:
while( is.get(c) ) {
v.push_back(c);
}

--
Michael
 
Reply With Quote
 
mathieu
Guest
Posts: n/a
 
      05-24-2011
On May 24, 2:03*pm, "Thomas J. Gritzan" <(E-Mail Removed)>
wrote:
> Am 24.05.2011 13:51, schrieb mathieu:
>
>
>
>
>
> > On May 24, 1:01 pm, Michael Doubez<(E-Mail Removed)> *wrote:
> >> On 24 mai, 11:16, gwowen<(E-Mail Removed)> *wrote:

>
> >>> On May 24, 9:58 am, mathieu<(E-Mail Removed)> *wrote:

>
> >>>> Dear all,

>
> >>>> * *I do not understand how to use the STL vector class with the
> >>>> ifstream class. I would like to reserve a chunk of memory (no
> >>>> initialization is required) and fill it with values from a file. As
> >>>> far as I understand vector::reserve requires a subsequent call to
> >>>> push_back or insert. However I do not see how I can do this in the
> >>>> following example:

>
> >>>> #include<fstream>
> >>>> #include<vector>

>
> >>>> int main(int argc, char *argv[])
> >>>> {
> >>>> * *const char *filename = argv[1];
> >>>> * *std::ifstream is( filename );
> >>>> * *const size_t l = 512;
> >>>> * *std::vector<char> *v;
> >>>> * *v.reserve( l ); // need push_back or insert

>
> >>> If you reserve() space, you can't read or write to that space until
> >>> you also adjust the size (as push_back() will, or resize()). *The
> >>> reserve() may well speed your code up.

>
> >>> char tmp;
> >>> is.read(&tmp,1);
> >>> v.push_back(tmp);

>
> >>> // the C++/STL like solution will use an istream_iterator and a
> >>> back_inserter
> >>> // I've got to say, I don't care for it...
> >>> vector<char> *V;
> >>> copy(istream_iterator<char>(is), istream_iterator<char>(),
> >>> back_inserter(V));

>
> >> Or simply:
> >> v.assign(stream_iterator<char>(is), istream_iterator<char>());

>
> > It does not work for me. istream_iterator does not implement +()
> > operator:

>
> > * *v.assign( std::istream_iterator<char>(is),
> > std::istream_iterator<char>(is)+l);

>
> You are not supposed to do +x on this.
>
> istream_iterator<char>(is) is an iterator refering to the begin of the
> stream while istream_iterator<char>() refers to the end of the stream,
> just like c.begin() and c.end() for any container.
> That pair of iterators reads from the stream until it hits the end of
> the stream (like end of file).
>
> If you want to read into a fixed buffer of std::vector:
>
> std::ifstream is( filename );
> const size_t size = 512;
> std::vector<char> buffer(size);


As said in my original post, I do not want to initialize the vector,
simply because this should not be required.

Thanks
 
Reply With Quote
 
mathieu
Guest
Posts: n/a
 
      05-24-2011
On May 24, 2:06*pm, Michael Doubez <(E-Mail Removed)> wrote:
> On 24 mai, 13:51, mathieu <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On May 24, 1:01*pm, Michael Doubez <(E-Mail Removed)> wrote:

>
> > > On 24 mai, 11:16, gwowen <(E-Mail Removed)> wrote:

>
> > > > On May 24, 9:58*am, mathieu <(E-Mail Removed)> wrote:

>
> > > > > Dear all,

>
> > > > > * I do not understand how to use the STL vector class with the
> > > > > ifstream class. I would like to reserve a chunk of memory (no
> > > > > initialization is required) and fill it with values from a file. As
> > > > > far as I understand vector::reserve requires a subsequent call to
> > > > > push_back or insert. However I do not see how I can do this in the
> > > > > following example:

>
> > > > > #include <fstream>
> > > > > #include <vector>

>
> > > > > int main(int argc, char *argv[])
> > > > > {
> > > > > * const char *filename = argv[1];
> > > > > * std::ifstream is( filename );
> > > > > * const size_t l = 512;
> > > > > * std::vector<char> v;
> > > > > * v.reserve( l ); // need push_back or insert

>
> > > > If you reserve() space, you can't read or write to that space until
> > > > you also adjust the size (as push_back() will, or resize()). *The
> > > > reserve() may well speed your code up.

>
> > > > char tmp;
> > > > is.read(&tmp,1);
> > > > v.push_back(tmp);

>
> > > > // the C++/STL like solution will use an istream_iterator and a
> > > > back_inserter
> > > > // I've got to say, I don't care for it...
> > > > vector<char> V;
> > > > copy(istream_iterator<char>(is), istream_iterator<char>(),
> > > > back_inserter(V));

>
> > > Or simply:
> > > v.assign(stream_iterator<char>(is), istream_iterator<char>());

>
> > It does not work for me. istream_iterator does not implement +()
> > operator:

>
> Yes, they are not random access input iterator.
>
>
>
> > * v.assign( std::istream_iterator<char>(is),
> > std::istream_iterator<char>(is)+l);

>

[...]
> is.get(c);
>
> And you loop:
> while( is.get(c) ) {
> * v.push_back(c);
>
> }


Ok. Let's hope multiple function calls are not expensive.

thanks
 
Reply With Quote
 
gwowen
Guest
Posts: n/a
 
      05-24-2011
On May 24, 1:52*pm, mathieu <(E-Mail Removed)> wrote:

> As said in my original post, I do not want to initialize the vector,
> simply because this should not be required.


In which case, reserve() the size, then push_back() the elements.
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      05-24-2011
mathieu <(E-Mail Removed)> wrote:
> const char *filename = argv[1];
> std::ifstream is( filename );
> const size_t l = 512;
> std::vector<char> v;
> v.reserve( l ); // need push_back or insert
> is.read( &v[0], l ); // ?


If the size of that buffer is indeed a compile-time constant, then you
could simply use a static array instead of std::vector. It will be much
more efficient that way too. (In fact, if you want it to be as efficient
as possible, use std::fread() instead of std::ifstream::read(), but that's
a different issue.)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
if and and vs if and,and titi VHDL 4 03-11-2007 05:23 AM



Advertisments