473,396 Members | 1,877 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Problems With strtof()

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I've written a program that requires the user to input a decimal number
which is then stored as a float.

First it's read into a variable buf which is an array of 16 characters
like this:
fgets(buf, 16, stdin);

I then tried to convert it into a float and store it in another variable.
val = strtof(buf, (char **)NULL);

For some reason, all numbers other than 0 are not being converted
properly. Am I doing something wrong?

I've changed the line of code to read like this:
val = (float)strtod(buf, (char **)NULL);

The second line of code is working fine, but it still bothers me that
the first one isn't.

If anyone wants to see the source a tarball is available at
ftp://linserv.homeip.net/src/tempconv
- --
Regards,
Jonathan Lamothe

QOTD:

"Backups are for wimps. Real men upload their data to an FTP site and
have everyone else mirror it."

-- Linus Torvalds
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCRxRBNrv4JaRC3JsRAsqwAJ483+dEEJYbR7nerGoGDw yBO4W2pACeJbrQ
kM69g/hPe60nF34XbYgnOoM=
=g0AN
-----END PGP SIGNATURE-----
Nov 14 '05 #1
10 6887
Jonathan Lamothe wrote:
I've written a program that requires the user to input a decimal number
which is then stored as a float.

First it's read into a variable buf which is an array of 16 characters
like this:
fgets(buf, 16, stdin);

I then tried to convert it into a float and store it in another variable.
val = strtof(buf, (char **)NULL);

For some reason, all numbers other than 0 are not being converted
properly. Am I doing something wrong?

I've changed the line of code to read like this:
val = (float)strtod(buf, (char **)NULL);

The second line of code is working fine, but it still bothers me that
the first one isn't.


The first line doesn't work because strtof() doesn't exist. Typo?

float val;
val = strtod(buf, NULL);

... will work just fine. strtod() doesn't need a cast and the second
argument is never cast. It would be used like this ..

float val;
char *endp;
val = strtod(buf, &endp);
--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #2
On Sun, 27 Mar 2005 15:14:57 -0500, Jonathan Lamothe
<jo**************@hotmail.com> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I've written a program that requires the user to input a decimal number
which is then stored as a float.

First it's read into a variable buf which is an array of 16 characters
like this:
fgets(buf, 16, stdin);
This looks reasonable.

I then tried to convert it into a float and store it in another variable.
val = strtof(buf, (char **)NULL);
The cast is unnecessary but also not harmful.

Unfortunately, there is no strtof in standard C before C99. Do you
really have a C99 compiler or is this a typo?

For some reason, all numbers other than 0 are not being converted
properly. Am I doing something wrong?
How do you know? What are you using to examine the result?

I've changed the line of code to read like this:
val = (float)strtod(buf, (char **)NULL);
Other than possibly silencing an obnoxious warning, the first cast is
irrelevant but again not harmful.

Why don't you create a char* and pass it's address so you can see
where the function is having a problem.

The second line of code is working fine, but it still bothers me that
the first one isn't.

If anyone wants to see the source a tarball is available at
ftp://linserv.homeip.net/src/tempconv


You have gone ballistic with casts. A cursory review shows that all
but two are absolutely unnecessary and I think the remaining two are
also unnecessary.

Of course, the fact that your code will not compile cleanly (undefined
identifier VERSION) doesn't lend any confidence that this is the
actual code you are talking about.

Your entire program is only about 170 lines. Why didn't you paste it
in so we could see what you were talking about?
<<Remove the del for email>>
Nov 14 '05 #3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Barry Schwarz wrote:
I then tried to convert it into a float and store it in another variable.
val = strtof(buf, (char **)NULL);

The cast is unnecessary but also not harmful.

Unfortunately, there is no strtof in standard C before C99. Do you
really have a C99 compiler or is this a typo?


Well, it's not a typo and it compiles, so I'm going to go out on a limb
and say that I have a C99 compiler. It's whatever came with my copy of
Linux.

Thanks for pointing that out, though. I'll keep it in mind from now on.
For some reason, all numbers other than 0 are not being converted
properly. Am I doing something wrong?

How do you know? What are you using to examine the result?


I know because in order to test the result, I followed it up with the
following line and watched the output:

printf("Resulting number: %f\n", val);

Every number I entered that wasn't zero became a rediculously large
negative number.
I've changed the line of code to read like this:
val = (float)strtod(buf, (char **)NULL);


Other than possibly silencing an obnoxious warning, the first cast is
irrelevant but again not harmful.

Why don't you create a char* and pass it's address so you can see
where the function is having a problem.


Worth a shot.
The second line of code is working fine, but it still bothers me that
the first one isn't.

If anyone wants to see the source a tarball is available at
ftp://linserv.homeip.net/src/tempconv


You have gone ballistic with casts. A cursory review shows that all
but two are absolutely unnecessary and I think the remaining two are
also unnecessary.


Unnecessary, but as you pointed out, not harmful. I cast everything
explicitly now, because I've lost count of the number of times where
I've written a program, and spent _days_ trying to find a bug caused by
the omission of a _seemingly_ unnecessary cast.
Of course, the fact that your code will not compile cleanly (undefined
identifier VERSION) doesn't lend any confidence that this is the
actual code you are talking about.
It is in fact the code I'm asking about. The VERSION identifier is
defined in the config.h file (which is automatically generated by the
configure shell script, and may vary depending on the system it's run on).

Note the three lines:
#if HAVE_CONFIG_H
#include <config.h>
#endif
Your entire program is only about 170 lines. Why didn't you paste it
in so we could see what you were talking about?


As you pointed out, the source file won't compile on it's own. It
requires a Makefile and configure.h, which are both generated by the
configure script.
- --
Regards,
Jonathan Lamothe

QOTD:

"Backups are for wimps. Real men upload their data to an FTP site and
have everyone else mirror it."

-- Linus Torvalds
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCR1ioNrv4JaRC3JsRAjGAAJ9gAYc43lIkA0ba22zIoE VM4k9IQQCgzvZ0
lOubnEkcsJBQCm1cT7G6ltE=
=DWg7
-----END PGP SIGNATURE-----
Nov 14 '05 #4
Jonathan Lamothe <jo**************@hotmail.com> wrote:
I've written a program that requires the user to input a decimal number
which is then stored as a float. First it's read into a variable buf which is an array of 16 characters
like this:
fgets(buf, 16, stdin); I then tried to convert it into a float and store it in another variable.
val = strtof(buf, (char **)NULL); For some reason, all numbers other than 0 are not being converted
properly. Am I doing something wrong?


I just created a small test program

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
char buf[ 16 ];
float val;

fgets( buf, 16, stdin );
val = strtof( buf, NULL );
printf( "%f\n", val );
return 0;
}

and it works just fine (compiled with gcc in C99 mode). So I can't
see anything from the code you posted that would keep it working
for you. And also the tempconv program from

ftp://linserv.homeip.net/src/tempconv

seems to work fine here after replacing strtod() to strtof() and
compiling it correctly, i.e. invoking gcc with the additional
option '-std=c99' to run it in C99 mode. So it doesn't seem to
be a C problem but one with gcc.

A few more comments concerning your tempconv program: you really go
over the top with your casts. E.g. "(float) 32" can also written as
"32.0" and is then much easier to read. And you don't need to cast
character constants like "(int) '\n'", contrary to what you might
expect character constants are always ints. The casts of the cases
in the switch constructs are also superfluous. Even the one before
the strlen() in read_string() isn't needed since you never get there
if the length of the input string is 0. While the casts here don't
hurt, they are rather annoying since normally a cast can be taken to
be a warning sign that at that place something unusual is going on
that may need careful checking. But by using lots and lots of unne-
cessary casts you cry "wolf" too often.

What you don't take into account is the user entering some invalid
numbers, which can nicely be dealt with by using the endptr argument
to strtof() and strtod()
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #5
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Je***********@physik.fu-berlin.de wrote:
I just created a small test program

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
char buf[ 16 ];
float val;

fgets( buf, 16, stdin );
val = strtof( buf, NULL );
printf( "%f\n", val );
return 0;
}

and it works just fine (compiled with gcc in C99 mode). So I can't
see anything from the code you posted that would keep it working
for you. And also the tempconv program from

ftp://linserv.homeip.net/src/tempconv

seems to work fine here after replacing strtod() to strtof() and
compiling it correctly, i.e. invoking gcc with the additional
option '-std=c99' to run it in C99 mode. So it doesn't seem to
be a C problem but one with gcc.
Maybe there's something wrong with my default libraries, then. :(
A few more comments concerning your tempconv program: you really go
over the top with your casts. E.g. "(float) 32" can also written as
"32.0" and is then much easier to read. And you don't need to cast
character constants like "(int) '\n'", contrary to what you might
expect character constants are always ints. The casts of the cases
in the switch constructs are also superfluous. Even the one before
the strlen() in read_string() isn't needed since you never get there
if the length of the input string is 0. While the casts here don't
hurt, they are rather annoying since normally a cast can be taken to
be a warning sign that at that place something unusual is going on
that may need careful checking. But by using lots and lots of unne-
cessary casts you cry "wolf" too often.
Yeah, I figured I was being a little over-paranoid with that. I've
already posted a second version where I've eliminated several
unnecessary casts.
What you don't take into account is the user entering some invalid
numbers, which can nicely be dealt with by using the endptr argument
to strtof() and strtod()


I kinda knew about that at the time. I'm just lazy. Maybe I'll deal
with that in the next release. ^^;
- --
Regards,
Jonathan Lamothe

QOTD:

"Backups are for wimps. Real men upload their data to an FTP site and
have everyone else mirror it."

-- Linus Torvalds
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCR3G5Nrv4JaRC3JsRAtF4AJ9NUaFOixUPg7Pu96hLuf +y8ZFjTwCeMyZn
ENQ4hTrohp0C9UKQFkd8Cw4=
=gDZb
-----END PGP SIGNATURE-----
Nov 14 '05 #6
Jonathan Lamothe wrote:
Barry Schwarz wrote:

.... snip ...

You have gone ballistic with casts. A cursory review shows that
all but two are absolutely unnecessary and I think the remaining
two are also unnecessary.


Unnecessary, but as you pointed out, not harmful. I cast
everything explicitly now, because I've lost count of the number
of times where I've written a program, and spent _days_ trying to
find a bug caused by the omission of a _seemingly_ unnecessary
cast.


An extremely poor practice. Most casts serve only to prevent
needed error messages. You probably have too low a warning level
set. The objective is not to quiet the compiler, but to write
correct code. Variadic function parameters are an exception to
this rule.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #7
Jonathan Lamothe <jo**************@hotmail.com> writes:
Barry Schwarz wrote:
I then tried to convert it into a float and store it in another variable.
val = strtof(buf, (char **)NULL);

The cast is unnecessary but also not harmful.

Unfortunately, there is no strtof in standard C before C99. Do you
really have a C99 compiler or is this a typo?


Well, it's not a typo and it compiles, so I'm going to go out on a limb
and say that I have a C99 compiler. It's whatever came with my copy of
Linux.


The strtof() function is defined by the runtime library, not by the
compiler. (The two together are part of the "implementation", which
is what the standard mostly refers to.)

What came with your copy of Linux is almost certainly gcc (the GNU
Compiler Collection, which includes a C compiler) and glibc, the GNU C
library.

A little experimentation on one of my Linux systems shows that the
strtof function is available in the library, but it doesn't appear in
<stdlib.h> *unless* you specify "-std=c99". (Without a declaration of
strtof in <stdlib.h>, I get incorrect results because there's an
implicit declaration as a function returning int; turning up the
warning level diagnoses the problem.)

gcc implements most, but not all, of C99; see
<http://gcc.gnu.org/c99status.html>.

It's common for pre-C99 implementations to provide some C99 features
as extensions (long long and "//" comments are particularly common).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #8
Je***********@physik.fu-berlin.de wrote:

A few more comments concerning your tempconv program: you really go
over the top with your casts. E.g. "(float) 32" can also written as
"32.0" and is then much easier to read.


Minor nit: 32.0 is (double)32 . In this specific case there will
be no difference, but there would be if the number in question
were not representable exactly as a float.

Nov 14 '05 #9
Jonathan Lamothe wrote:

I cast everything explicitly now, because I've lost count of the
number of times where I've written a program, and spent _days_
trying to find a bug caused by the omission of a _seemingly_
unnecessary cast.


If I may use an analogy: that's like wearing full plate armour
to avoid getting your legs cut when you have to walk through
brambles. IMHO you would be better off to understand the
principle behind the bug. Then you would know in advance when
to use a cast, rather than using trial-and-error.

It sounds like the bugs you encountered were due to not grokking
the type of an expression; for example: double x = 3 / 4; (the
type of '3' and '4' is int, so the result still has type 'int'),
or: unsigned y = 1; int x = (-1 < y); (both operands must have the
same type, so -1 is converted to unsigned int before the comparison
occurs).

Nov 14 '05 #10
"Old Wolf" <ol*****@inspire.net.nz> writes:
Jonathan Lamothe wrote:
I cast everything explicitly now, because I've lost count of the
number of times where I've written a program, and spent _days_
trying to find a bug caused by the omission of a _seemingly_
unnecessary cast.


If I may use an analogy: that's like wearing full plate armour
to avoid getting your legs cut when you have to walk through
brambles. IMHO you would be better off to understand the
principle behind the bug. Then you would know in advance when
to use a cast, rather than using trial-and-error.


Except that full plate armo[u]r really would protect you from
brambles.

A better analogy would be disconnecting the warning lights on your
car's dashboard rather than correcting the problem that caused the
lights to come on.

If your compiler gives you a diagnostic message, and adding a cast
turns off the message, the chances are good that the diagnostic was
correct, and the cast hasn't actually fixed anything.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Jim Hubbard | last post by:
Are you up to speed on the difficulties in using the 1.1 .Net framework? Not if you are unaware of the 1,596 issues listed at KBAlertz (http://www.kbalertz.com/technology_3.aspx). If you are...
1
by: 3f | last post by:
Hello; We have made a web application that people can download from our web site and installed on: Windows XP Windows 2000 Professional Windows 2003 Server Windows 2000 Server
5
by: Corky | last post by:
This works: db2 SELECT DISTINCT PROBLEM_OBJECTS.PROBLEM_ID FROM PROBLEM_OBJECTS INNER JOIN PROBLEMS ON PROBLEM_OBJECTS.PROBLEM_ID = PROBLEMS.PROBLEM_ID WHERE INTEGER(DAYS(CURRENT DATE) -...
11
by: Marcus Jacobs | last post by:
Dear Group I am encountering a precision issue while converting a text string to a float using STRTOF. For example, at times a text string "736.00000" (quotation marks added) is converted to...
11
by: Marcus Jacobs | last post by:
Dear Group I have written a file conversion program that uses strtof to convert text strings to floats. It works as I intended except for my error messages. It is my understanding that strtof...
10
by: BBFrost | last post by:
We just recently moved one of our major c# apps from VS Net 2002 to VS Net 2003. At first things were looking ok, now problems are starting to appear. So far ... (1) ...
0
by: Sergistm | last post by:
Hello World, :D I have a problem that it is making me crazy, I hope you can help me. I'm trying to execute a .exe file with the Procces.Start, and there is no problem when the file is on my...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.