Why does strtof not print proper float? - c

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

Related

Implicit declaration in C language

Consider the following quote from the C book by Dennis ritchie
All variables must be declared before use, although certain
declarations can be made implicitly by content.
It is known that all variables of any type must be declared before using it further. I am unaware with the latter part of the statement that certain declarations can be made implicitly
by content.
In C, in general, the variables fall under four basic data types char, int, float, double. How can a variable from these datatypes can be used without any declaration before. Please provide an example that shows implicit declaration based on content the variable holds.
By "certain declarations" the author means declaration of things which are not variables. At the time the book has been written C allowed implicit declaration of functions: the compiler simply assumed that the function returns integer. Modern C standards make such declarations illegal.
When the first edition of K&R was written, there was no C standard. When the second edition of K&R was written, the C89/C90 standard was about to be finalized. Because of the legacy from code written before C89 was finalized, the standard had to permit:
#include <stdio.h>
double sqrt();
main(argc, argv)
char **argv;
{
if (argc > 1)
printf("sqrt(%s) = %f\n", argv[1], sqrt((double)atoi(argv[1])));
else
printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2.0));
return 0;
}
Note that the return type of main() is implicitly int; the function argument argc is implicitly int; the function atoi() has an implicit return type of int. Note too that the argument to sqrt() had to be explicitly a double value; the compiler could not automatically convert the argument type because prototypes were not a part of C before the C89 standard.
Such code is no longer acceptable to C99 or C11 compilers. You could use:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc > 1)
printf("sqrt(%s) = %f\n", argv[1], sqrt(atoi(argv[1])));
else
printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2));
return 0;
}
This uses the standard headers to declare the functions with complete prototypes, so it is no longer necessary to cast the argument to sqrt(). In C99 or C11, you could omit the return 0; and the effect would be the same. Personally, I don't like the loophole that allows that and continue to write the return explicitly. The return was necessary in C90 to send a determinate status to the environment (e.g. the shell the invoked the program).

Is the %zu specifier required for printf?

We are using C89 on an embedded platform. I attempted to print out a size_t, but it did not work:
#include <stdio.h>
int main(void) {
size_t n = 123;
printf("%zu\n",n);
return 0;
}
Instead of 123, I got zu.
Other specifiers work correctly.
If size_t exists shouldn't zu also be available in printf?
Is this something I should contact my library vendor about, or is a library implementation allowed to exclude it?
If size_t exists shouldn't zu also be available in printf?
size_t existed at least since C89 but the respective format specifier %zu (specifically the length modifier z) was added to the standard only since C99.
So, if you can't use C99 (or C11) and had to print size_t in C89, you just have to fallback to other existing types, such as:
printf("%lu\n", (unsigned long)n);
size_t is returned by sizeof(). %zu specifier prints the length.So to return the size of n,the code should read: #include <stdio.h>
int main(void) { size_t n=123; printf("%zu\n",sizeof (n)); return 0;` }
This is working fine. In my system, it's printing the expected value.
You may be getting the error due to the compiler. I am using the GCC compiler. If you have this only and trying to get the output the first update the GCC and then try. It will work.

fabs vs. fabsl, should I ever have to type fabsl in my source?

I'm rewriting some Mac code that embeds a freeware library originally written in C. The compiler is complaining that since I'm using long double, I should use fabsl rather than fabs. So I went and changed them.
However, reading a few pages on the topic it seems that there should be no difference, that ever since C99, there is a type generic macro that inserts the correct call based on type.
So perhaps I am using the wrong dialect?
Does anyone know what the Compiler Default is in xcode7, and whether it has the generic macro?
The generic macro is defined in <tgmath.h>, so you need to #include it, as shown in the following snippet:
#include <tgmath.h>
#include <stdio.h>
int main() {
long double ld = 3.14;
double d = 3.14;
float f = 3.14f;
printf("%Lf %lf, %f\n",fabs(ld), fabs(d), fabs(f));
return 0;
}
It compiles flawlessly with
gcc -Wall -Wextra a.c -oa -std=c99

Why does strtof always output 0.0000?

Calling strtof with a floating point number runs fine on my local machine but on the school's servers strtof always returns 0.000000. I checked to see if there was anything stored in errno since a 0 should mean an error, but it says success. Does anyone have an idea why this might be?
Here is the code.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%f\n", strtof(argv[1],0));
return 0;
}
Short version: compile with -std=gnu99 or -std=c99. Explanation follows.
I've reproduced a similar "problem" on my own box. However, when I try to compile:
# gcc -Wall -o float float.c
float.c: In function 'main':
float.c:6: warning: implicit declaration of function 'strtof'
float.c:6: warning: format '%f' expects type 'double', but argument 2 has type 'int'
So I looked at the man page for strtof(), and it says:
SYNOPSIS
#include <stdlib.h>
double strtod(const char *nptr, char **endptr);
#define _XOPEN_SOURCE=600 /* or #define _ISOC99_SOURCE */
#include <stdlib.h>
float strtof(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);
What that means is that one of those values has to be #defined before including stdlib.h. However, I just recompiled with -std=gnu99, and that defines one of those for me and it works.
# gcc -std=gnu99 -Wall -o float float.c
# ./float 2.3
2.300000
Moral: always compile with -Wall. ;-)
Have you included the header where strtof is defined (stdlib.h), otherwise you may get 0.0 since by default unknown functions in C are treated as returning int.

why is strtof is always evaluating to HUGE_VAL?

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.

Resources