sscanf'ing floats into structure members

B

Bernard Liang

(Using GCC) Simplified excerpt:

typedef struct {
double a;
double b;
double c;
} my_type;

int read(FILE* fp, my_type* data) {
char src_buffer[1024];
char q[16];
float utc_time;
...
sscanf(src_buffer, "%12s %f %f %f %f\n", q, &utc_time, &(data->a),
&(data->b), &(data->c));
}
Suppose that src_buffer looks like " 13:39:55.871 204234.000000
3746.741211 -12223.571289 20.279785\n".

For some reason, it is stuffing 0.0's into data->a, data->b, and
data->c. Why is that? I can't seem to figure out why this can possibly
be happening. Is there a problem with my implementation of what I am
trying to do? The alternative is to make other temporary floats and then
to assign them to data->a ... (which works), but this shouldn't be
necessary.

-Bernard Liang
 
M

Michael Mair

Bernard said:
(Using GCC) Simplified excerpt:

Do not give us "as if" code but a real, compiling minimal
example.
typedef struct {
double a;
double b;
double c;
} my_type;

int read(FILE* fp, my_type* data) {

Note: Make clear _what_ you are reading by giving the function
a telling name. As soon as you "read" a second kind of data,
you are stuck with read() and readOtherData().
char src_buffer[1024];
char q[16];
float utc_time;
...
sscanf(src_buffer, "%12s %f %f %f %f\n", q, &utc_time, &(data->a),
&(data->b), &(data->c));

Your forgot to check whether the return value of sscanf() is 5.

Your main mistake, though, is to use a float* format for a double*
argument. Use "%lf" instead.

You forgot to return something at the end of the function.
}
Suppose that src_buffer looks like " 13:39:55.871 204234.000000
3746.741211 -12223.571289 20.279785\n".

Give us real input data. Avoid line breaks;
" 13:39:55.871 204234.000000"
" 3746.741211 -12223.571289"
" 20.279785\n"
is just as good.
For some reason, it is stuffing 0.0's into data->a, data->b, and
data->c. Why is that? I can't seem to figure out why this can possibly
be happening. Is there a problem with my implementation of what I am
trying to do? The alternative is to make other temporary floats and then
to assign them to data->a ... (which works), but this shouldn't be
necessary.

This usually is not necessary.

If the code you posted is close enough to your real code,
your problem is an FAQ,
http://www.c-faq.com/stdio/scanf2.html
If it is not, then this is an excellent example why you should
post real code.

Cheers
Michael
 
E

Eric Sosman

Bernard Liang wrote On 06/21/06 13:53,:
(Using GCC) Simplified excerpt:

typedef struct {
double a;
double b;
double c;
} my_type;

int read(FILE* fp, my_type* data) {
char src_buffer[1024];
char q[16];
float utc_time;
...
sscanf(src_buffer, "%12s %f %f %f %f\n", q, &utc_time, &(data->a),
&(data->b), &(data->c));
}
Suppose that src_buffer looks like " 13:39:55.871 204234.000000
3746.741211 -12223.571289 20.279785\n".

For some reason, it is stuffing 0.0's into data->a, data->b, and
data->c. Why is that?

Because "%f" generates a float value and stores it
via the matching float*. You want to store double values
through double* pointers, so you should use "%lf".

You mention you're using gcc, which happens to be one
of the compilers that can generate helpful warnings for
this sort of mismatch -- if you ask it politely:

gcc -W -Wall -ansi -pedantic ...

(You might want to specify a different level of Standard
conformance by changing -ansi to something else; check the
info screens.)
 
K

Keith Thompson

Bernard Liang said:
(Using GCC) Simplified excerpt:

typedef struct {
double a;
double b;
double c;
} my_type;

int read(FILE* fp, my_type* data) {
char src_buffer[1024];
char q[16];
float utc_time;
...
sscanf(src_buffer, "%12s %f %f %f %f\n", q, &utc_time, &(data->a),
&(data->b), &(data->c));
}

For sscanf, "%f" expects a pointer to float. &utc_time is of the
correct type, but the following three arguments are all pointers to
double. Use "%lf" for a pointer to double (or "%Lf" for a pointer to
long double).
 

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,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top