How to convert string to float?
Asked Answered
L

9

65
#include<stdio.h>
#include<string.h>

int main() 
{
    char s[100] ="4.0800" ; 

    printf("float value : %4.8f\n" ,(float) atoll(s)); 
    return 0; 
}

I expect the output should be 4.08000000 whereas I got only 4.00000000.

Is there any way to get the numbers after the dot?

Leucoma answered 31/10, 2011 at 7:42 Comment(0)
E
75

Use atof() or strtof()* instead:

printf("float value : %4.8f\n" ,atof(s)); 
printf("float value : %4.8f\n" ,strtof(s, NULL)); 

https://cplusplus.com/reference/cstdlib/atof/
https://cplusplus.com/reference/cstdlib/strtof/

  • atoll() is meant for integers.
  • atof()/strtof() is for floats.

The reason why you only get 4.00 with atoll() is because it stops parsing when it finds the first non-digit.

*Note that strtof() requires C99 or C++11.

Edric answered 31/10, 2011 at 7:43 Comment(5)
printf("float value : %4.8f\n" , atof(s)); # output : float value : 0.00000000Leucoma
Downvoted for recommending atof, which ignores parse errors, instead of strtof. You should know better ;-)Appleby
@Zack Can't say I knew that even existed two years ago. Especially since it seems to be a C99/C++11 function.Edric
@Edric Oh, right, all the short-float functions were C99. But strtod is in C89 and has the same advantage over atof (unambiguously reporting parse errors).Appleby
Note that atof() returns a double, despite its name. The analogue is strtod() as strtof() returns float, and strtold() returns long double.Chrysanthemum
H
37

Unfortunately, there is no way to do this easily. Every solution has its drawbacks.

  1. Use atof() or strtof() directly: this is what most people will tell you to do and it will work most of the time. However, if the program sets a locale or it uses a library that sets the locale (for instance, a graphics library that displays localised menus) and the user has their locale set to a language where the decimal separator is not . (such as fr_FR where the separator is ,) these functions will stop parsing at the . and you will stil get 4.0.

  2. Use atof() or strtof() but change the locale; it's a matter of calling setlocale(LC_ALL|~LC_NUMERIC, ""); before any call to atof() or the likes. The problem with setlocale is that it will be global to the process and you might interfer with the rest of the program. Note that you might query the current locale with setlocale() and restore it after you're done.

  3. Write your own float parsing routine. This might be quite quick if you do not need advanced features such as exponent parsing or hexadecimal floats.

Also, note that the value 4.08 cannot be represented exactly as a float; the actual value you will get is 4.0799999237060546875.

Hypotension answered 31/10, 2011 at 7:57 Comment(0)
H
31

Why one should not use function atof() to convert string to double?

On success, atof() function returns the converted floating point number as a double value. If no valid conversion could be performed, the function returns zero (0.0). If the converted value would be out of the range of representable values by a double, it causes undefined behavior.

Refrence:http://www.cplusplus.com/reference/cstdlib/atof/

Instead use function strtod(), it is more robust.

Try this code:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    char s[100] = "4.0800";
    printf("Float value : %4.8f\n",strtod(s,NULL));
    return 0;
}

You will get the following output:

Float value : 4.08000000

Horvath answered 31/7, 2014 at 12:14 Comment(4)
Excellent, I was trying to find the bug using atof() for 2 hours until I saw this. Thx!Ondrej
Note that strtod is locale-dependent. See sam hocevar's answer for details.Ur
Isn't strtod out of scope for a question tagged c ? I know it is a C++ one but well, I am looking for ANSI C :cIrmgard
@LudovicZenohateLagouardette strtod() is defined in C and is in scope. (C11dr 7.22.1.3 The strtod, strtof, and strtold functions)Pembrook
S
5

Use atof()

But this is deprecated, use this instead:

const char* flt = "4.0800";
float f;
sscanf(flt, "%f", &f);

http://www.cplusplus.com/reference/clibrary/cstdlib/atof/

atof() returns 0 for both failure and on conversion of 0.0, best to not use it.

Spoiler answered 31/10, 2011 at 7:45 Comment(6)
Suggesting sscanf() instead isn't any better. I would suggest strtod() instead.Accidental
printf("float value : %4.8f\n" , atof(s)); # output : float value : 0.00000000Leucoma
"Use atof() But this is deprecated," --> please post a reference.Pembrook
@chux Even if atof() isn't deprecated, it's imprecise, dangerous and ultimately useless for writing robust code. atof() should never be used. It has no way to return an error, and if the input is beyond the representable range undefined behavior is invoked. So the only way to safely use it is to fully parse the input some other way and make sure the input is valid before calling atof() - thus making atof() utterly useless.Centigram
@AndrewHenle No reason to consider atof() has any precision difference than strtod() - so imprecise-ness is not an issue. atof() has overflow UB as does *scanf(flt, "%f", &f); - all of which do not presently meet "robustness". atof() has limited uses: Example: Insuring a string is made up of (-,+,0-9,.) and has a length below, say 30, is trivially versus to re-writing atof(). Calling atof() on such a string has well defined behavior. IAC, as of C11 (and I think also C17), atof() is not depreciated - so answer is factual incorrect & sscanf() here offers no improvement.Pembrook
@chux I'd consider returning a valid value of 0.0 upon an error a form of imprecision. And given the glibc implementation, rewriting atof() is, well, pretty trivial. Insuring a string is made up of (-,+,0-9,.) and has a length below, say 30 My point is you only need to do that if you're using atof(), or some similarly-non-robust function such as one of the *scanf() family (which IMO are much worse in many ways than atof() - I deliberately wasn't commenting on the use of scanf() here...)Centigram
A
1

By using sscanf we can convert string to float.

#include<stdio.h>    
#include<string.h>    

int main() 
{
    char str[100] ="4.0800" ;     
    const char s[2] = "-";   
    char *token;
    double x;
   /* get the first token */ 
   token = strtok(str, s);
   sscanf(token,"%f",&x);
    printf( " %f",x );

    return 0; 
}
Auric answered 5/1, 2017 at 5:5 Comment(0)
S
1

Reminder: While using atof(), make sure you don't have "" in your string. atof("1.123") will return 0.000 or something like that.

Solution

str_val[0] = "0";
str_val[len-1] = "\n"; //len = length of string
Stemma answered 8/4, 2022 at 1:33 Comment(0)
A
0

You want to use the atof() function.

http://www.cplusplus.com/reference/clibrary/cstdlib/atof/

Alon answered 31/10, 2011 at 7:44 Comment(0)
C
-2
double x;

char *s;

s = " -2309.12E-15";

x = atof(s);     /* x = -2309.12E-15 */

printf("x = %4.4f\n",x);
Czardas answered 28/5, 2013 at 21:48 Comment(0)
G
-3
Main()  {
    float rmvivek,arni,csc;
    char *c="1234.00";
    csc=atof(c);
    csc+=55;
    printf("the value is %f",csc);
}
Garonne answered 12/12, 2014 at 16:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.