Parsing Variable # of Data Fields after fgets

  • Thread starter Michael R. Copeland
  • Start date
M

Michael R. Copeland

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
 
R

Richard Heathfield

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.
 
M

Michael R. Copeland

I have a problem parsing the following data:
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.
 
G

Gordon Burditt

I have a problem parsing the following data:
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
 
S

Stan Milam

Michael said:
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;
}
 
S

Stan Milam

Michael said:
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.
 
C

Chuck F.

Michael said:
>
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) {
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/>
 
R

Richard Heathfield

Michael R. Copeland said:
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, 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.
 

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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top