input formatted file

J

Jun

hello,

I've a data file

========
4 1 1 1 1
5 1 1 1 1 1
2 1 1
========

first column represents the how many values in this line, and then
followed by values. I've seen some codes using

*******************************
ifstream inf

while(inf >> data1 >> data2)
*******************************
to read data, just very beautiful and simple code, could anyone give
me some advices for my case? thank you in advance.


Jun
 
R

Ron AF Greve

Hi,

Not tested, but my guess would be something like:

#include <vector>
#include <iostream>
using namespace std;

//........
try
{
unsigned long Cnt = 0;
while( inf >> Cnt )
{
vector<unsigned long> Data;
for( unsigned long CntData = 0; CntData < Cnt; ++CntData )
{
unsigned long Item = 0;
if( !( inf >> Item ) )
{
throw "Unexpeceted end of file";
}
Data.push_back( Item );
}
// Do something with data
}
}
catch( const char *Error )
{
cerr << Error << endl;
}
Regards, Ron AF Greve

http://www.InformationSuperHighway.eu
 
J

Jim Langston

Jun said:
hello,

I've a data file

========
4 1 1 1 1
5 1 1 1 1 1
2 1 1
========

first column represents the how many values in this line, and then
followed by values. I've seen some codes using

*******************************
ifstream inf

while(inf >> data1 >> data2)
*******************************
to read data, just very beautiful and simple code, could anyone give
me some advices for my case? thank you in advance.

One thing I would do is use std::getline( inf, somestring );
then put it into a stringstream.
std::stringstream Data( somestring );
At this point you can check if the number of values are correct.

int Count;
if ( Data >> Count )
{
int Value;
int ValueCount;
while ( Data >> Value )
{
ValueCount++;
// dosomething with Value
}
if ( ValueCount != Count )
{
// throw error here. Number at beginning does not match
// number of values.
}
}

If you don't use a stringstream but just do
while ( inf >> Number )
you can't be sure if you're reading data or the count. If you were supposed
to be reading 5 values, such as the lines
5 1 1 1 1
2 1 1

It would read the next lines 2 as a value, grab the next 1 as a count, then
read the next 1 as a value, if you understand.

but getline will only read one line, which you can validate the count if you
need to.
 
J

Jun

One thing I would do is use std::getline( inf, somestring );
then put it into a stringstream.
std::stringstream Data( somestring );
At this point you can check if the number of values are correct.

int Count;
if ( Data >> Count )
{
int Value;
int ValueCount;
while ( Data >> Value )
{
ValueCount++;
// dosomething with Value
}
if ( ValueCount != Count )
{
// throw error here. Number at beginning does not match
// number of values.
}

}

If you don't use a stringstream but just do
while ( inf >> Number )
you can't be sure if you're reading data or the count. If you were supposed
to be reading 5 values, such as the lines
5 1 1 1 1
2 1 1

It would read the next lines 2 as a value, grab the next 1 as a count, then
read the next 1 as a value, if you understand.

but getline will only read one line, which you can validate the count if you
need to.

the following code
================
std::stringstream Data( somestring );
================

just doesn't work
 
J

Jim Langston

Jun said:
the following code
================
std::stringstream Data( somestring );
================

just doesn't work

std::string somestring("5 1 1 1 1");
std::stringstream Data( somestring );

make sure somestring is a std::string
you could call it anything, "somestring" was just a foo name.

Make sure you
#include <string>
#include <sstream>
 
J

James Kanze

One thing I would do is use std::getline( inf, somestring );
then put it into a stringstream.

Why a stringstream, and not an istringstream? You don't want to
write to it?
std::stringstream Data( somestring );
At this point you can check if the number of values are correct.
int Count;
if ( Data >> Count )
{
int Value;
int ValueCount;
while ( Data >> Value )
{
ValueCount++;
// dosomething with Value
}
if ( ValueCount != Count )
{
// throw error here. Number at beginning does not match
// number of values.
}
}

Even easier:

std::istringstream s( line ) ;
size_t count ;
s >> count ;
std::vector< int > data((std::istream_iterator< int >( s )),
(std::istream_iterator< int >()) ) ;
if ( ! s ) {
// Some input error...
} else if ( data.size() != count ) {
// syntax error
}
 
J

Jim Langston

One thing I would do is use std::getline( inf, somestring );
then put it into a stringstream.

Why a stringstream, and not an istringstream? You don't want to
write to it?

----------

I don't use streams that often other than stringstream where I do tend to do
both input and output and the full blown stringstream is required. I'm not
100% sure of the advantages of using istringstream over stringstream though,
other than maybe some overhead costs.
std::stringstream Data( somestring );
At this point you can check if the number of values are correct.
int Count;
if ( Data >> Count )
{
int Value;
int ValueCount;
while ( Data >> Value )
{
ValueCount++;
// dosomething with Value
}
if ( ValueCount != Count )
{
// throw error here. Number at beginning does not match
// number of values.
}
}

Even easier:

std::istringstream s( line ) ;
size_t count ;
s >> count ;
std::vector< int > data((std::istream_iterator< int >( s )),
(std::istream_iterator< int >()) ) ;
if ( ! s ) {
// Some input error...
} else if ( data.size() != count ) {
// syntax error
}
 
J

James Kanze

"James Kanze" <[email protected]> wrote in message

[...]
Why a stringstream, and not an istringstream? You don't want to
write to it?
I don't use streams that often other than stringstream where I
do tend to do both input and output and the full blown
stringstream is required. I'm not 100% sure of the advantages
of using istringstream over stringstream though, other than
maybe some overhead costs.

Two important benefits: it expresses your intent better, and if
you slip up, and type a >> instead of a <<, the compiler will
complain. (The < and the > keys are adjacent on a US keyboard,
so if your right hand is slightly out of position, it's a likely
typo.)

It's interesting that you usually use both directions, however.
I've never had a case where I've needed a bi-directional
iostream, of any type. I can imagine them with fstream,
however, at least if you open the fstream in binary mode. I
can't even image a case where you would want one for a
stringstream, however. Are you using them as some sort of
temporary file? If so, why---what's the advantage compared to
simply saving the raw data in its internal format?
 
J

Jim Langston

"James Kanze" <[email protected]> wrote in message

[...]
Why a stringstream, and not an istringstream? You don't want to
write to it?
I don't use streams that often other than stringstream where I
do tend to do both input and output and the full blown
stringstream is required. I'm not 100% sure of the advantages
of using istringstream over stringstream though, other than
maybe some overhead costs.

Two important benefits: it expresses your intent better, and if
you slip up, and type a >> instead of a <<, the compiler will
complain. (The < and the > keys are adjacent on a US keyboard,
so if your right hand is slightly out of position, it's a likely
typo.)

It's interesting that you usually use both directions, however.
I've never had a case where I've needed a bi-directional
iostream, of any type. I can imagine them with fstream,
however, at least if you open the fstream in binary mode. I
can't even image a case where you would want one for a
stringstream, however. Are you using them as some sort of
temporary file? If so, why---what's the advantage compared to
simply saving the raw data in its internal format?

-------------------------

template<typename T, typename F > T StrmConvert( const F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}
 
J

James Kanze

"James Kanze" <[email protected]> wrote in message

[...]
template<typename T, typename F > T StrmConvert( const F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

That's boost::lexical_cast. Which is probably what I'd use if I
ever needed it. I'll admit that I never saw the utility of
boost::lexical_cast either. And I'm rather sceptical of using
iostream inserters and extractors for this, too.

Consider something like:

std::complex< double > z( 1.0, 0.0 ) ;
double x = boost::lexical_cast< double >( z ) ;

The result should obviously be 1.0. Your code will return 0.0,
and boost::lexical_cast will raise some sort of exception.

IMHO, the example showcases both problems:

-- converting a type A to a type B makes no sense in
general---you have to define exactly what is meant, for each
case (What should std::complex< double >( 0.0, 1.0 )
return when converted to double?), and

-- whatever definition you use, the >> and << won't necessarily
do the trick.

(I wonder if this isn't some sort of larger anti-pattern:
providing a generic solution for a problem which doesn't have a
generic solution.)
 
K

Kai-Uwe Bux

James said:
[...]
It's interesting that you usually use both directions, however.
I've never had a case where I've needed a bi-directional
iostream, of any type. I can imagine them with fstream,
however, at least if you open the fstream in binary mode. I
can't even image a case where you would want one for a
stringstream, however. Are you using them as some sort of
temporary file? If so, why---what's the advantage compared to
simply saving the raw data in its internal format?
template<typename T, typename F > T StrmConvert( const F from )
{
std::stringstream temp;
temp << from;
T to = T();
temp >> to;
return to;
}

That's boost::lexical_cast. Which is probably what I'd use if I
ever needed it. I'll admit that I never saw the utility of
boost::lexical_cast either. And I'm rather sceptical of using
iostream inserters and extractors for this, too.

Consider something like:

std::complex< double > z( 1.0, 0.0 ) ;
double x = boost::lexical_cast< double >( z ) ;

The result should obviously be 1.0.

There is nothing obvious about this.
Your code will return 0.0,
and boost::lexical_cast will raise some sort of exception.

And how would boost be wrong? Seems like the RightThing(tm) to do in this
case.

IMHO, the example showcases both problems:

-- converting a type A to a type B makes no sense in
general---you have to define exactly what is meant, for each
case (What should std::complex< double >( 0.0, 1.0 )
return when converted to double?), and

-- whatever definition you use, the >> and << won't necessarily
do the trick.

(I wonder if this isn't some sort of larger anti-pattern:
providing a generic solution for a problem which doesn't have a
generic solution.)

I don't think that there is such an anti-pattern. Whether a problem has a
generic solution or not very much depends on how you phrase it. E.g., the
standard containers all overload operator< although there is no natural
order on sequences of type T even for types T that have an ordered set of
values. Nonetheless it makes perfect sense to settle on an order for
sequences so that you can use them as keys in maps.

As for the particular case of lexical_cast, I found good uses of it. But I
also have generic IO for pairs, sequences, tuples, and so on because it
makes perfect sense in the context of my code-base to have such operations
available. Then lexical_cast provides convenient way, e.g., to initialize
data in small test programs like so:

matrix< double > A =
lexical_cast< matrix< double > >( "[ [ 1.0 0.2 ] [ 0.0 -1.9 ] ]" );

That conveys content much better than all alternatives.


Best

Kai-Uwe Bux
 
J

James Kanze

James said:
"James Kanze" <[email protected]> wrote in message
[...]
That's boost::lexical_cast. Which is probably what I'd use if I
ever needed it. I'll admit that I never saw the utility of
boost::lexical_cast either. And I'm rather sceptical of using
iostream inserters and extractors for this, too.
Consider something like:
std::complex< double > z( 1.0, 0.0 ) ;
double x = boost::lexical_cast< double >( z ) ;
The result should obviously be 1.0.
There is nothing obvious about this.

There's nothing obvious about the fact that the complex number
1+0i should become simply 1 when converted to double? I'm not a
mathematician, but I don't see what else would be reasonable.
And how would boost be wrong? Seems like the RightThing(tm) to
do in this case.

I don't know. It might be the right thing to do for something
like complex<double>(0.0,1.0), but here, I rather doubt it.

Either way, it highlights the crux of the problem: the behavior
of the conversion is really randomly defined, with no regard to
what might be relative semantics. It's a case of doing
something because you can, not because it has any meaning.
I don't think that there is such an anti-pattern. Whether a
problem has a generic solution or not very much depends on how
you phrase it.

There's definitely an anti-pattern of defining generic solutions
when they're not appropriate. std::pair and boost::lexical_cast
being good examples.
E.g., the standard containers all overload operator< although
there is no natural order on sequences of type T even for
types T that have an ordered set of values. Nonetheless it
makes perfect sense to settle on an order for sequences so
that you can use them as keys in maps.

That's a bit different. One might argue that there is a design
flaw in requiring order where there isn't a logical order (e.g.
making map and set ordered). In this particular case, there are
pragmatic considerations involved as well, however.

It probably would have been cleaner if the standard containers
had only defined a specialization of less, rather than the
operator<. Arguably, < has a specific meaning which isn't
applicable here. (And that is really your argument: that
operator overloading has been abused.) But the results serve a
very definite pragmatic purpose. You may disagree with the
relationship between the operator and the semantics associated
with it (arbitrary ordering, for use in ordered containers), but
that doesn't mean that providing a generic solution for those
semantics is necessarily wrong.
As for the particular case of lexical_cast, I found good uses
of it. But I also have generic IO for pairs, sequences,
tuples, and so on because it makes perfect sense in the
context of my code-base to have such operations available.
Then lexical_cast provides convenient way, e.g., to initialize
data in small test programs like so:
matrix< double > A =
lexical_cast< matrix< double > >( "[ [ 1.0 0.2 ] [ 0.0 -1.9 ] ]" );
That conveys content much better than all alternatives.

Hmmm. I'd have thought a constructor taking a string or an
istream would be more appropriate. Otherwise, a generic
conversion to/from string might be something to consider; I
don't seen anything wrong generic toString() and fromString
functions, for example. To/from just anything, however, using
the string representation as an intermediary, is, however,
unnecessary genericity.
 
K

Kai-Uwe Bux

James said:
James said:
[...]
That's boost::lexical_cast. Which is probably what I'd use if I
ever needed it. I'll admit that I never saw the utility of
boost::lexical_cast either. And I'm rather sceptical of using
iostream inserters and extractors for this, too.
Consider something like:
std::complex< double > z( 1.0, 0.0 ) ;
double x = boost::lexical_cast< double >( z ) ;
The result should obviously be 1.0.
There is nothing obvious about this.

There's nothing obvious about the fact that the complex number
1+0i should become simply 1 when converted to double? I'm not a
mathematician, but I don't see what else would be reasonable.

a) Nothing else would be reasonable.

b) That does not imply that returning the real part is reasonable. You seem
to assume that there must be a reasonable conversion from complex to real
(and since all other candidates are non-reasonable, it must be this one).
That's is somewhat like: We must do something, this is something, we must
do this.

The only natural map is the inclusion R >--> C. There is no natural map in
the other direction. That is why conversion from complex to real should
fail but conversion from real to complex ought to work.

I don't know. It might be the right thing to do for something
like complex<double>(0.0,1.0), but here, I rather doubt it.

Either way, it highlights the crux of the problem: the behavior
of the conversion is really randomly defined, with no regard to
what might be relative semantics. It's a case of doing
something because you can, not because it has any meaning.

Correct, lexical_cast<> is very much like reinterpret_cast<>. It just
chooses a different intermediate representation for the conversion (string
as opposed to bit-pattern). However, that is not a problem with the
definition of lexical_cast<>; it just shows that you have to give some
thought to whether you want to use it. I think, that is the reason for
the "cast" part in the name.

There's definitely an anti-pattern of defining generic solutions
when they're not appropriate. std::pair and boost::lexical_cast
being good examples.

I would conjecture that you are just not facing the problems that
std::pair<> solves. Defining std::pair is most definitely not an
anti-pattern. In my math programming, std::pair just corresponds to taking
cross-products. That is very useful and expressed intend very clearly. It
might be an abstraction that does little for you, but it works very well in
the problem domain that is of interest to me. The only anti-pattern in
sight would be to use std::pair where you shouldn't.

That's a bit different. One might argue that there is a design
flaw in requiring order where there isn't a logical order (e.g.
making map and set ordered). In this particular case, there are
pragmatic considerations involved as well, however.

That is not different from any other case. There are always pragmatic
considerations and in the end usefulness of a solution (be it generic or
not) ultimately decides.
It probably would have been cleaner if the standard containers
had only defined a specialization of less, rather than the
operator<. Arguably, < has a specific meaning which isn't
applicable here. (And that is really your argument: that
operator overloading has been abused.) But the results serve a
very definite pragmatic purpose. You may disagree with the
relationship between the operator and the semantics associated
with it (arbitrary ordering, for use in ordered containers), but
that doesn't mean that providing a generic solution for those
semantics is necessarily wrong.

I was not the one arguing that an overly generic solution is wrong. The one
calling that an anti-pattern was you. I just gave operator< as an examply
for why I don't believe your claim that defining generic solutions that can
be used beyond their natural domain of applicability is an anti-pattern. I
have to admit that I do prefer useful designs to clean ones. (Now, if you
can have both, then that's even better.)

From my point of view, it is better to have a library component that can be
misused but solves the problem it is supposed to solve to a library
component that tries to prevent misuse at the cost of restricted
applicability. I think a library should be by and large trusting to the
judgement of its clients. Thus, I don't mind a certain excess-genericity.

As for the particular case of lexical_cast, I found good uses
of it. But I also have generic IO for pairs, sequences,
tuples, and so on because it makes perfect sense in the
context of my code-base to have such operations available.
Then lexical_cast provides convenient way, e.g., to initialize
data in small test programs like so:
matrix< double > A =
lexical_cast< matrix< double > >( "[ [ 1.0 0.2 ] [ 0.0 -1.9 ] ]" );
That conveys content much better than all alternatives.

Hmmm. I'd have thought a constructor taking a string or an
istream would be more appropriate. Otherwise, a generic
conversion to/from string might be something to consider; I
don't seen anything wrong generic toString() and fromString
functions, for example.

I find it very clean to put the code for formatting in operator<< and the
code for reading in data in operator>> and be done with it. To have
additional constructors from stream or string smells like code doublication
to me. The generic toString and fromString very close to lexical_cast. In
either case, both ways just provide some syntactic sugar for conversion to
and from string that are available as soon as operator>> and operator<< are
defined.

To/from just anything, however, using
the string representation as an intermediary, is, however,
unnecessary genericity.

As I said, it is just convenient syntactic sugar. With the conversion
functions you suggested, one could write

target = fromString<target_type>( toString( source ) );

I see very little difference. In my code, almost all lexical_cast go from or
to string anyway. (However, that is mostly because I prefer the crazy
reinterpretations to take place through piping on the command line.)


Best

Kai-Uwe Bux
 
P

Pavel Shved

hello,

I've a data file

========
4 1 1 1 1
5 1 1 1 1 1
2 1 1
========

first column represents the how many values in this line, and then
followed by values. I've seen some codes using

*******************************
ifstream inf

while(inf >> data1 >> data2)
*******************************
to read data, just very beautiful and simple code, could anyone give
me some advices for my case? thank you in advance.

something like

int n,X;
for (inf >> n; inf && n--? (inf >> X , /* output X somewhere */ ) :
inf >> n ; );


True beautiful one is reading list of numbers ending with a zero:

while (inf >> n, n)
{ //read them }
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top