why is strtof is always evaluating to HUGE_VAL? - c

What could be the issue here? It doesn't matter what number I choose for str, it is always 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
char *str = "2.6";
printf("%f\n", strtof(str, (char**)NULL));
//prints 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
whole program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *str = "2.6";
printf("%f\n", strtof(str, NULL));
return 1;
}
compile with -Wall:
test4.c:7: warning: implicit declaration of function âstrtofâ

What platform are you building for/on? The warning that you say is being emitted:
test4.c:7: warning: implicit declaration of function âstrtofâ
indicates that the compiler doesn't know that strtof() returns a float, so it's going to push an int to the printf() call instead of a double. strtof() is normally declared in stdlib.h, which you're including. But it wasn't a standard function until C99, so the exact compiler platform (and configuration/options you're using) may affect whether it's being made available or not.

strtof is defined in C99 only. It may be that passing the option -std=c99 to the compiler will fix it since default GCC (-std=gnu89) includes only a few C99 features.
Another option is to use the C89-kosher strtod. Which is probably the better option in the long run, anyways. (When do you need singles except in exceptional circumstances?)

Perhaps you've forgotten to include the correct header(s)?
#include <stdlib.h>
#include <stdio.h>
int main() {
printf("%f\n", strtof("2.6", NULL));
return 0;
}
produces:
2.600000
for me...

Given your warnings, you should try adding -std=c99 to get the C99 standard definitions from the header. By default it will assume that the return value is an int and then try to convert that to a float. This will obviously be wrong. Alternatively you could simply supply your own, correct declaration for strtof().

As the others have said, you need -std=c99. But you can also use strtod() which is string to double, and you don't need -std=c99 for that.
I was having problems with strtof() on CentOS 5.5 with glibc 2.5 unless I used -std=c99, but strtod() worked perfectly.

Related

why is this behaviour of strtof() changes with respect to the change in stdlib.h?

With <stdlib.h> included the following code gives the output of 123.34.
#include<stdlib.h>
int main()
{
char *str="123.34";
float f= strtof(str,NULL);
printf("%f",f);
}
But without <stdlib.h> it produces the output of 33.000000.
What is the role of <stdlib.h> here and why did the value 33.00000 occur when it is nowhere in the code?
You must take a look at the warning generated by the compiler.
warning: implicit declaration of function 'strtof' [-Wimplicit-function-declaration]
This still yields result, which is not deterministic in any way because the return type expected is float, whereas without the header inclusion, the default is assumed to be int.
If you look into the stdlib header file, there is a declaration,
float strtof(const char *restrict, char **restrict);
With #include<stdlib.h>, we provide this declaration. When missed, compiler assumes to be returning int, and hence the result is not deterministic.
With my system, it produced 0.00000000 as the output, whereas with the necessary inclusions, I got 123.339996 as the output.
As a precaution, make a habit of always compiling the code with -Wall option (Assuming that you are using gcc), or better yet, -Werror option.
The <stdlib.h> header tells the compiler that strtof() returns a float(); in its absence, the compiler is forced to assume it returns an int. Modern C compilers (GCC 5 and above) complain about the absence of a declaration for strtof() and/or a conflict with its internal memorized declaration for strtof().
If you omit <stdlib.h>, your code is unacceptable in C99 and C11 because you didn't declare strtof() before using it. Since you omit <stdio.h>, it is invalid in C90, let alone C99 or C11. You must declare variadic functions such as printf() before using them.

Why does strtof not print proper float?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char aaa[35] = "1.25";
char* bbb = &(aaa[0]);
char** ccc = &(bbb);
float a = strtof(*ccc, ccc);
printf("%f\n", a);
return 0;
}
The code I wrote above should print 1.25, but according to codepad (online C compiler), it does not print 1.25. On codepad, it prints 2097152.000000 . Here's the codepad link
What have I done wrong here?
codepad has an old version of gcc, and presumably of the standard C library. Apparently, strtof is not being declared by the header files you include. (strtof was added in C99.)
Try using an online service with a postdiluvian version of gcc. Or explicitly add the correct declaration:
float strtof(const char* ptr, char** end_ptr);
What's happening is that without the declaration, the compiler defaults the return type of the function to int. Since the function actually returns a float, the float is being interpreted as (not converted to) an integer, and then that integer is converted to a float.
No warning is produced, presumably because -Wall is not in the compiler options, and/or the C standard being used allows the use of non-declared functions.

HPUX atof doesn't convert string to double

I'm fetching the version number of an hpux machine and trying to convert it to a float using atof, but this happens:
#include <stdio.h>
#include <sys/utsname.h>
int main(int argc, char *argv[]) {
struct utsname u;
uname(&u);
char* release = u.release;
while (*release != '.')
release++;
release++;
printf("%s\n", release);
printf("%f\n", atof(release));
}
prints this:
# ./test
11.31
0.000000
Returning double 0 just means the conversion failed. The utsname man page says the strings are null terminated, so I don't understand why the atof command is failing. Am I making some kind of obvious mistake here?
The atof function is declared in <stdlib.h>.
If you call it without the required #include <stdlib.h>, the most likely result is that (a) your compiler will print a warning (which you've apparently ignored), and (b) the compiler will assume that atof returns an int result.
Add
#include <stdlib.h>
to the top of your source file. And pay attention to compiler warnings. If you didn't get a warning, find out how to invoke your compiler in a way that makes it warn about this kind of thing. (I don't know what compiler you're using, so I can't offer specifics.) For gcc, the compiler you're using, the -Wall option will enable this warning.
Some background:
Prior to the 1999 edition of the ISO C standard, it was permitted to call a function with no visible declaration. The compiler would assume that the function takes arguments of the (promoted) types passed in the call, and that it returns a result of type int. This typically would work correctly if the function actually does return an int, and if you write the call correctly (and if the function is not variadic, like printf).
The 1999 version of the standard ("C99") dropped the "implicit int" rule, making any call to a function with no visible declaration a constraint violation, requiring a diagnostic (which can be a non-fatal warning). Many compilers, will merely warn about the error and then handle the call under the older rules. And gcc still doesn't enforce C99 rules by default; its default dialect is "GNU90", consisting of the 1990 ISO C standard plus GNU-specific extensions. You can ask it to use C99 semantics with "-std=c99"; to enforce those semantics, you can use "-std=c99 -pedantic" or "-std=c99 -pedantic-errors".
Newer versions of gcc (partially) support the latest 2011 standard if you specify "-std=c11".
See the gcc 4.8.2 manual for details.

C: convert argv[1] to double

I need to pass a double to my program, but the following does not work:
int main(int argc, char *argv[]) {
double ddd;
ddd=atof(argv[1]);
printf("%f\n", ddd);
return 0;
}
If I run my program as ./myprog 3.14 it still prints 0.000000.
Can somebody please help?
My guess is you forgot to include #include <stdlib.h>. If this is the case, gcc will issue the following warning:
warning: implicit declaration of function 'atof' [-Wimplicit-function-declaration]
And give the exact output you provided: 0.000000.
As remyabel indicated, you probably neglected to #include <stdlib.h>. The reason this matters is that, without having a declaration of atof(), the C standard mandates that the return value is assumed to be int. In this case, it's not int, which means that the actual behavior you observe (getting a return value of 0) is technically unspecified.
To be clear, without the double-returning declaration, the line ddd=atof(argv[1]) is treated as a call to an int-returning function, whose result is then cast to a double. It is likely the case that the calling conventions on the particular system you're on specify that ints and doubles get returned in different registers, so the 0 is likely just to be whatever happened to be in that particular register, while the double return value is languishing, unobserved.
In C you don't require to declare a function before you use it (in contrast with C++), and if that happens (no prototype), compiler makes some assumptions about that function. One of those assumptions is that it returns int. There's no error, atof() works, but it works incorrectly. It typically get whatever value happens to be in the register where int is supposed to be returned (it is 0 in your case, but it can be something else).
P.S. atof() and atoi() hide input errors (which you can always see by adding option -Wall to your gcc compiler call: gcc -Wall test.c), so most people prefer to use strtol() and strtod() instead.

c sscanf and SCNu64 compile error

I don't understand the below error message when I compile this code. I couldn't find out what wrong with it.
Description Resource Path Location
Type expected ‘)’ before ‘SCNu64’.
#include <inttypes.h>
int calc_rate(uint64_t *rate, char val[], char mult[]) {
int rc = sscanf(val, "%" SCNu64 "%2s", rate, mult);
}
If you have both <inttypes.h> and <stdio.h> included, then the code fragment shown compiles cleanly. (You can't call sscanf() legally unless there's a prototype in scope.) That means the problem is in the code prior to what you are showing. Or it means that your compiler doesn't provide support for exactly 64-bit types, which is rather unlikely unless you're on a relatively obscure mainframe, or you aren't compiling in C99 or C11 mode.

Resources