Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Valarray input from file

Reply
Thread Tools

Valarray input from file

 
 
Daniel Brewer
Guest
Posts: n/a
 
      07-19-2004
Hi there,

I would like to define a general operator>> function for valarrays that
allows the input of an arbitary sized array from a file. An example data
file would be like:
0 1 2 3 4 5 6
4 5 6 7 8 9 10 11 12

With each line defining a different valarray. Is it possible to do this?
So far I have:

std::istream& operator>>( std::istream& is, std::valarray<double>& t )
{
for(i=0;;i++)
{
t.resize(i+1);
is >> t[i];
if (is.eof()) break;
}

return is;
}


but this does not seem to work.

Any ideas what the best approach to this would be?

Thanks

Dan
 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      07-19-2004

"Daniel Brewer" <> wrote in message
news:cdghrl$3070$...
> Hi there,
>
> I would like to define a general operator>> function for valarrays that
> allows the input of an arbitary sized array from a file. An example data
> file would be like:
> 0 1 2 3 4 5 6
> 4 5 6 7 8 9 10 11 12
>
> With each line defining a different valarray. Is it possible to do this?


Its possible but I'm not sure its a good idea because it contradicts every
other operator>> which treat newlines in the same way as every other kind of
whitespace.

I'm not saying you shouldn't write a routine to do this, I just don't think
you should call it operator>>

> So far I have:
>
> std::istream& operator>>( std::istream& is, std::valarray<double>& t )
> {
> for(i=0;;i++)
> {
> t.resize(i+1);
> is >> t[i];
> if (is.eof()) break;
> }
>
> return is;
> }
>
>
> but this does not seem to work.


Well, one reason it doesn't work is that you aren't testing for a newline
anywhere.

>
> Any ideas what the best approach to this would be?
>


How about this ugly (and untested) code

#include <iostream>
#include <sstream>
#include <string>
#include <iterator>
#include <valarray>
#include <vector>

std::istream& read_valarray(std::istream& in, std::valarray<double>& val)
{
// read a line
std::string line;
std::getline(in, line);

// copy line to a vector
std::vector<double> temp_vec;
std::istringstream buf(line);
std::copy(std::istream_iterator<double>(buf),
std::istream_iterator<double>(buf),
std::back_inserter(temp_vec));

// copy the vector to the valarray
val.resize(temp_vec.size());
val = std::valarray<double>(&temp_vec[0], temp_vec.size());
return in;
}

john


 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      07-19-2004
> std::copy(std::istream_iterator<double>(buf),
> std::istream_iterator<double>(buf),
> std::back_inserter(temp_vec));
>


Should be

std::copy(std::istream_iterator<double>(buf),
std::istream_iterator<double>(),
std::back_inserter(temp_vec));

As I said, untested code.

john


 
Reply With Quote
 
Daniel Brewer
Guest
Posts: n/a
 
      07-19-2004
John Harrison wrote:

>> std::copy(std::istream_iterator<double>(buf),
>> std::istream_iterator<double>(buf),
>> std::back_inserter(temp_vec));
>>

>
>
> Should be
>
> std::copy(std::istream_iterator<double>(buf),
> std::istream_iterator<double>(),
> std::back_inserter(temp_vec));
>
> As I said, untested code.
>
> john
>
>

Thanks I will give it ago. So a standard operator>> ignores all
carriage returns, spaces etc. In that case maybe I should define a
"normal" operator>> and then adapt the resulting valarray some how.

Thanks for your help

Dan Brewer
 
Reply With Quote
 
Buster
Guest
Posts: n/a
 
      07-19-2004
Daniel Brewer wrote:

> I would like to define a general operator>> function for valarrays that
> allows the input of an arbitary sized array from a file. An example data
> file would be like:
> 0 1 2 3 4 5 6
> 4 5 6 7 8 9 10 11 12
>
> With each line defining a different valarray. Is it possible to do this?
> So far I have:
>
> std::istream& operator>>( std::istream& is, std::valarray<double>& t )
> {
> for(i=0;;i++)
> {
> t.resize(i+1);
> is >> t[i];
> if (is.eof()) break;
> }
>
> return is;
> }
>
>
> but this does not seem to work.
>
> Any ideas what the best approach to this would be?


John's right, you should be using std::getline.

Another reason your function won't work is that 'resize' is destructive,
replacing the old valarray with a zero-initialized valarray of the new
size. This is described on page 666 of "The C++ Programming Language"
(3rd/Special edition). Bad omen?

You need to create your own valarray of the new size, and copy the old
contents across each time. All this copying will take time, so it's
probably best to allocate a larger valarray than you need, so you have
to resize less often. All this would be taken care of if you used a
vector instead of a valarray.

--
Regards,
Buster.
 
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
Why not use valarray<valarray<T> > ? Jim West C++ 2 12-23-2003 03:54 PM
const and valarray reference Jim West C++ 4 10-24-2003 08:30 PM
Enhancing valarray with "normal" arithmetic operators =?ISO-8859-1?Q?Christian_Brechb=FChler?= C++ 6 09-14-2003 06:39 PM
Re: valarray resize Marc Schellens C++ 5 07-30-2003 07:06 AM
New Altivec-optimized valarray implementation Glen Low C++ 3 06-26-2003 05:07 AM



Advertisments