Creating a fixed length output string with sprintf containing floats

10,602

Solution 1

You can force the sign to be printed, too with the + prefix: printf( "+3.6f", 1.0 ); will result in a fixed size printout.

(courtesy to the handiest printf documentation I ever saw).

Solution 2

Why not just write a binary file, where the sign bit isn't a concern? Added benefit is that (in general) you'll be writing 12 bytes vs 32 for each item (a green solution :-). After all, you lose precision when doing a sprintf and an atof on the other side.

If this isn't viable,

int len_lng = lng < 0 ? 6: 7;
int len_lat = lat < 0 ? 6: 7;
char fmt[128];
sprintf(fmt, "%%10i %%3.%df %%3.%df\n", len_lng, len_lat);
sprintf(osm_node_repr, fmt, node->id, node->lng, node->lat);
Share:
10,602
Kungi
Author by

Kungi

I currently have the pleasure to develop clojure / clojurescript applications for fun and profit.

Updated on June 04, 2022

Comments

  • Kungi
    Kungi almost 2 years

    I'm trying to create a file which has the following structure:
    - Each line has 32 bytes - Each line looks like this format string: "%10i %3.7f %3.7f\n"

    My Problem is the following: When i have a negative floating point numbers the line gets longer by one or even two characters because the - sign does not count to the "%3.7f".

    Is there any way to do this more nicely than this?

    if( node->lng > 0 && node->lat > 0 ) { 
        sprintf( osm_node_repr, "%10i %3.7f %3.7f\n", node->id, node->lng, node->lat );
    } else if (node->lng > 0 && node->lat < 0) {
        sprintf( osm_node_repr, "%10i %3.7f %3.6f\n", node->id, node->lng, node->lat );
    } else if (node->lng < 0 && node->lat > 0) {
        sprintf( osm_node_repr, "%10i %3.6f %3.7f\n", node->id, node->lng, node->lat );
    } else if ( node->lng < 0 && node->lat < 0 ) { 
        sprintf( osm_node_repr, "%10i %3.6f %3.6f\n", node->id, node->lng, node->lat );
    }
    

    Thanks for your Answers,
    Andreas

  • Puppy
    Puppy almost 14 years
    This. The question is tagged C++, and I'm not sure why the OP is writing C code here.
  • Kungi
    Kungi almost 14 years
    Thank you that is exactly what i was looking for.
  • xtofl
    xtofl almost 14 years
    I agree strongly with losslessly writing 'valuable data'. +1!
  • Kungi
    Kungi almost 14 years
    Writing a binary file is definitely worth consideration. I didn't even think of that. Thanks for the idea.
  • Kungi
    Kungi almost 14 years
    I'm using this code in a C++ program so I tagged the question with C++ but obviously this is wrong :-). Thanks
  • tomlogic
    tomlogic almost 14 years
    Writing floats in a binary file is fine as long as the file is always read by the same program. Also, you can use '*' in your format to allow passing of the width or precision as an argument.