4

I'm programming on a AVR XMEGA microcontroller, using AtmelStudio.

I'm having trouble converting a string to a float. The string is called token2 and has the value "8.604165"

I've already tried a couple of functions:

  • float lon = atof(token2); printf("lon=%f", lon); returns lon=?
  • float lon = strtod(token2, NULL); printf("lon=%f", lon); returns lon=?
  • float lon = strtof(token2, NULL); printf("lon=%f", lon); gives an error undefined reference to strtof, even including <stdlib.h>

Am I doing something wrong?

  • Your code can be fine: [look at this example](http://ideone.com/azrwwH) – LPs Aug 25 '16 at 13:26
  • 4
    Please post a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). Are you writing some code for microcontroller? If so, please specify the environment. Might be related: [c - Arduino: printf/fprintf prints question mark instead of float - Stack Overflow](http://stackoverflow.com/questions/14146850/arduino-printf-fprintf-prints-question-mark-instead-of-float) – MikeCAT Aug 25 '16 at 13:29
  • Yes @MikeCAT. I'm programming on a AVR XMega microcontroller – Francisco Estêvão Aug 25 '16 at 13:42
  • 1
    Looks like your problem is with `printf`, not with the conversion. Try `printf("lon=%f", 8.604165);`, and tell us what you see. BTW, in the third bullet, I wouldn't describe it as '**returns an error**' since there's no "return" here (it's a compilation error, not a runtime error). – barak manos Aug 25 '16 at 13:46
  • In addition, please use a debugger and tell us what is the value of `lon` after calling `atof` and after calling `strtod`. – barak manos Aug 25 '16 at 13:52
  • does the code have the statement: `#include `? Is the code being compiled with one fo these defined: ` _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L; or cc -std=c99` – user3629249 Aug 26 '16 at 23:22

2 Answers2

6

By default, AVR-libc tries to save space in the binary by not linking in floating-point-related stuff. For functions like atof that's easy because if you don't call them then the linker won't include them. For printf, though, the linker can't tell whether you're planning on using it for floating-point numbers.

Instead, AVR-libc has multiple libraries which define printf. The printf in the default library has full functionality except that it doesn't support floating-point numbers. If you want to save space in your binary and you're not using the more advanced features of printf (namely format flags), you can link with printf_min to replace that with a teenier version. And if you want to print floating-point numbers, you need the full powered version defined in printf_flt.

This page describes the proper linker options to select those alternative versions. In short, add -Wl,-u,vfprintf -lprintf_flt -lm to your linker options.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
0

Ok, so this is something specific of microcontrollers.

Similar to what @Sneftel said, I just had to add the libraries libprintf_flt.a and libm.a in AtmelStudio.

  • 3
    It's not just specific to this IDE, this approach is fairly common with smaller microcontrollers as processing floats adds quite a bit of bloat to your code size for space constrained devices. In some devices floating point math is absent completely, others it's an linker option to vary the included version. – crlanglois Aug 25 '16 at 15:07