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

Parsing Variable # of Data Fields after fgets

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


P: n/a
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)
Dec 24 '05 #2

P: n/a
> > 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.
Dec 25 '05 #3

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

P: n/a
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;
}
Dec 25 '05 #5

P: n/a
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.
Dec 25 '05 #6

P: n/a
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/>
Dec 26 '05 #7

P: n/a
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)
Dec 26 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.