Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Parsing Variable # of Data Fields after fgets (http://www.velocityreviews.com/forums/t440646-parsing-variable-of-data-fields-after-fgets.html)

Michael R. Copeland 12-24-2005 11:22 PM

Parsing Variable # of Data Fields after fgets
 
I'm processing a control file comprised of many types of lines, with
some containing variable data. I have a problem parsing the following
data:
18 12.2 7.145 6.214 Phase distances
First, I've read the entire line and have manually extracted the
record type (18). Now I must parse the (3) real values that follow,
only knowing (from other data previously read) that there are 3 values
there. The number of blanks separating the fields can vary, too.
I can use sscanf, I suppose, by coding a series of switch-based calls
that have 1-n %f format specifiers and 1-n array element references -
but that's cumbersome and limiting (if I encounter more data than I've
coded for). There must be a way to do this common sort of thing, but I
can't see it. 8<{{ Any thoughts? TIA

Richard Heathfield 12-24-2005 11:42 PM

Re: Parsing Variable # of Data Fields after fgets
 
Michael R. Copeland said:

> I'm processing a control file comprised of many types of lines, with
> some containing variable data. I have a problem parsing the following
> data:
> 18 12.2 7.145 6.214 Phase distances
> First, I've read the entire line and have manually extracted the
> record type (18). Now I must parse the (3) real values that follow,
> only knowing (from other data previously read) that there are 3 values
> there. The number of blanks separating the fields can vary, too.
> I can use sscanf, I suppose, by coding a series of switch-based calls
> that have 1-n %f format specifiers and 1-n array element references -
> but that's cumbersome and limiting (if I encounter more data than I've
> coded for). There must be a way to do this common sort of thing, but I
> can't see it. 8<{{ Any thoughts? TIA


Consider the wonderful flexibility that a loop offers you.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

Michael R. Copeland 12-25-2005 01:31 AM

Re: Parsing Variable # of Data Fields after fgets
 
> > I have a problem parsing the following data:
> > 18 12.2 7.145 6.214 Phase distances
> > First, I've read the entire line and have manually extracted the
> > record type (18). Now I must parse the (3) real values that follow,
> > only knowing (from other data previously read) that there are 3 values
> > there. The number of blanks separating the fields can vary, too.
> > I can use sscanf, I suppose, by coding a series of switch-based calls
> > that have 1-n %f format specifiers and 1-n array element references -
> > but that's cumbersome and limiting (if I encounter more data than I've
> > coded for). There must be a way to do this common sort of thing, but I
> > can't see it. 8<{{ Any thoughts? TIA

>
> Consider the wonderful flexibility that a loop offers you.
>

Sure...but _how_ do I do it? With sscanf? Some other way? If
sscanf, please explain how it's done.

Gordon Burditt 12-25-2005 03:05 AM

Re: Parsing Variable # of Data Fields after fgets
 
>> > I have a problem parsing the following data:
>> > 18 12.2 7.145 6.214 Phase distances
>> > First, I've read the entire line and have manually extracted the
>> > record type (18). Now I must parse the (3) real values that follow,
>> > only knowing (from other data previously read) that there are 3 values
>> > there. The number of blanks separating the fields can vary, too.
>> > I can use sscanf, I suppose, by coding a series of switch-based calls
>> > that have 1-n %f format specifiers and 1-n array element references -
>> > but that's cumbersome and limiting (if I encounter more data than I've
>> > coded for). There must be a way to do this common sort of thing, but I
>> > can't see it. 8<{{ Any thoughts? TIA

>>
>> Consider the wonderful flexibility that a loop offers you.
>>

> Sure...but _how_ do I do it? With sscanf? Some other way? If
>sscanf, please explain how it's done.


Functions such as strtol(), strtod(), and strtoul() give you back
a pointer to the *END* of the data it used for the number. If it's
NULL, there was an error, if it's not, that's a good starting point
for looking for the next number.

Gordon L. Burditt

Stan Milam 12-25-2005 03:34 AM

Re: Parsing Variable # of Data Fields after fgets
 
Michael R. Copeland wrote:
>>> I have a problem parsing the following data:
>>>18 12.2 7.145 6.214 Phase distances
>>> First, I've read the entire line and have manually extracted the
>>>record type (18). Now I must parse the (3) real values that follow,
>>>only knowing (from other data previously read) that there are 3 values
>>>there. The number of blanks separating the fields can vary, too.
>>> I can use sscanf, I suppose, by coding a series of switch-based calls
>>>that have 1-n %f format specifiers and 1-n array element references -
>>>but that's cumbersome and limiting (if I encounter more data than I've
>>>coded for). There must be a way to do this common sort of thing, but I
>>>can't see it. 8<{{ Any thoughts? TIA

>>
>>Consider the wonderful flexibility that a loop offers you.
>>

>
> Sure...but _how_ do I do it? With sscanf? Some other way? If
> sscanf, please explain how it's done.

#include <stdio.h>

int
main( void )
{
int x;
double a, b, c;
char inbuf[100];
char string[] = "18 12.2 7.145 6.214 Phase Differences\n";

sscanf(string, "%d", &x);
switch( x ) {
case 18 :
sscanf( string,
"%*d %lf %lf %lf %[^\n]%*c",
&a,
&b,
&c,
inbuf
);
break;

default :
break;
}

printf("%lf %lf %lf %s\n", a, b, c, inbuf);
return 0;
}

Stan Milam 12-25-2005 03:39 AM

Re: Parsing Variable # of Data Fields after fgets
 
Michael R. Copeland wrote:

>>> I have a problem parsing the following data:
>>>18 12.2 7.145 6.214 Phase distances
>>> First, I've read the entire line and have manually extracted the
>>>record type (18). Now I must parse the (3) real values that follow,
>>>only knowing (from other data previously read) that there are 3 values
>>>there. The number of blanks separating the fields can vary, too.
>>> I can use sscanf, I suppose, by coding a series of switch-based calls
>>>that have 1-n %f format specifiers and 1-n array element references -
>>>but that's cumbersome and limiting (if I encounter more data than I've
>>>coded for). There must be a way to do this common sort of thing, but I
>>>can't see it. 8<{{ Any thoughts? TIA

>>
>>Consider the wonderful flexibility that a loop offers you.
>>

>
> Sure...but _how_ do I do it? With sscanf? Some other way? If
> sscanf, please explain how it's done.


I forgot to mention that sscanf() is great for this kind of application.
It is very powerful and you should grab your manual and read
thouroughly how it works. And, there are other ways to do it also. If
you want I'll post another example of a different way to do it.

Stan.

Chuck F. 12-26-2005 02:41 AM

Re: Parsing Variable # of Data Fields after fgets
 
Michael R. Copeland wrote:
>
>>> I have a problem parsing the following data: 18 12.2 7.145
>>> 6.214 Phase distances First, I've read the entire line and
>>> have manually extracted the record type (18). Now I must
>>> parse the (3) real values that follow, only knowing (from
>>> other data previously read) that there are 3 values there.
>>> The number of blanks separating the fields can vary, too. I
>>> can use sscanf, I suppose, by coding a series of
>>> switch-based calls that have 1-n %f format specifiers and
>>> 1-n array element references - but that's cumbersome and
>>> limiting (if I encounter more data than I've coded for).
>>> There must be a way to do this common sort of thing, but I
>>> can't see it. 8<{{ Any thoughts? TIA

>>
>> Consider the wonderful flexibility that a loop offers you.
>>

> Sure...but _how_ do I do it? With sscanf? Some other way? If
> sscanf, please explain how it's done.


Please do not remove attribution lines for material you quote.

For example:

double realvals[3];
integer i, rectype;

if (1 != scanf("%d", &rectype) barf();
else {
switch (rectype) {
....
18: for (i = 0; i < 3; i++) {
if (1 != scanf{"%d", %realvals[i]) {
barf(); break;
}
dothingswith(realvals);
flushln(stdin); /* NOT fflush, you write this */
break;
....
default:
barf(); /* unknown rectype */
}
}

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>

Richard Heathfield 12-26-2005 06:02 AM

Re: Parsing Variable # of Data Fields after fgets
 
Michael R. Copeland said:

>> Consider the wonderful flexibility that a loop offers you.
>>

> Sure...but _how_ do I do it? With sscanf? Some other way? If
> sscanf, please explain how it's done.


find n, the number of fields on the line (which, apparently, you can do
already), and then do this:

for(i = 0; i < n; i++)
{
read a field from the line into array element[i], and don't lose track of
how far you've got along the line
}


Sure you could use sscanf. Or strtod. Or a home-rolled routine. Or whatever.
C is a very flexible language.

Personally, for this, I'd use a function that captures a whole line as a
string - I have a home-rolled routine for doing this but you could use
fgets if your inputs are sufficiently tame - and then do the conversions
using strtod, because it facilitates progressing neatly through the string.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)


All times are GMT. The time now is 12:49 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57