sscanf'ing floats into structure members

Discussion in 'C Programming' started by Bernard Liang, Jun 21, 2006.

  1. (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
     
    Bernard Liang, Jun 21, 2006
    #1
    1. Advertising

  2. Bernard Liang

    Michael Mair Guest

    Bernard Liang schrieb:
    > (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-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Jun 21, 2006
    #2
    1. Advertising

  3. Bernard Liang

    Eric Sosman Guest

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

    --
     
    Eric Sosman, Jun 21, 2006
    #3
  4. Bernard Liang <> writes:
    > (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).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jun 21, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JFCM
    Replies:
    4
    Views:
    5,741
  2. John
    Replies:
    13
    Views:
    708
  3. ravi
    Replies:
    0
    Views:
    455
  4. Kosio

    Floats to chars and chars to floats

    Kosio, Sep 16, 2005, in forum: C Programming
    Replies:
    44
    Views:
    1,295
    Tim Rentsch
    Sep 23, 2005
  5. mathog

    sscanf up to 127 characters into a buffer?

    mathog, Mar 14, 2013, in forum: C Programming
    Replies:
    20
    Views:
    877
    Shao Miller
    Mar 17, 2013
Loading...

Share This Page