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

Valarray input from file

P: n/a
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
Jul 22 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a

"Daniel Brewer" <da******@brewer.me.uk> wrote in message
news:cd***********@uns-a.ucl.ac.uk...
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
Jul 22 '05 #2

P: n/a
> 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
Jul 22 '05 #3

P: n/a
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
Jul 22 '05 #4

P: n/a
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.
Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.