Bill said:
But I don't understand why you will consider
it a failure if the user enters "0"--that seems like a valid
input. It might be more appropriate to check
for *endptr == argv[1], or perhaps **endptr == '\0'.
I changed endptr to a char *. I don't think it really matters as I
would be de-referencing that variable anyway. I would like to hear why
you prefer that approach. Is it code readability?
Here's a working version:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
int
main(int argc, char **argv) {
char *endptr;
char *input;
double output;
input = argv[1];
if(argc < 2) {
(void)printf("usage: strtof <digit>\n");
exit(1);
}
output = strtod(input, &endptr);
if (input[0] == '\0' || *endptr != '\0') {
perror("string to double conversion failed");
exit(1);
}
(void)printf("%f\n", (float)output);
exit(0);
}
Here are some debugging results:
$ gdb strtof
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "amd64-unknown-openbsd4.0"...
(gdb) break main
Breakpoint 1 at 0x40089f: file strtof.c, line 13.
(gdb) run 0a1b2c
Starting program: /anime/strtof 0a1b2c
Breakpoint 1, main (argc=2, argv=0x7f7ffffec080) at strtof.c:13
13 input = argv[1];
(gdb) info locals
endptr = 0x7f7ffffec070 ""
input = 0x7f7ffffec528 "/anime/strtof"
output = 4.1461860541929491e-317
(gdb) step
14 if(argc < 2) {
(gdb) step
19 output = strtod(input, &endptr);
(gdb) until
20 if (input[0] == '\0' || *endptr != '\0') {
(gdb) info locals
endptr = 0x7f7ffffec537 "a1b2c"
input = 0x7f7ffffec536 "0a1b2c"
output = 0
(gdb) p *endptr
$1 = 97 'a'
(gdb) p input[0]
$2 = 48 '0'
(gdb) step
21 perror("string to double conversion failed");
(gdb)
and here are some results to show that I can now enter a 0 as a valid
entry:
$ gdb strtof
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "amd64-unknown-openbsd4.0"...
(gdb) break main
Breakpoint 1 at 0x40089f: file strtof.c, line 13.
(gdb) run 0
Starting program: /anime/strtof 0
Breakpoint 1, main (argc=2, argv=0x7f7fffff5d18) at strtof.c:13
13 input = argv[1];
(gdb) info locals
endptr = 0x7f7fffff5d00 ""
input = 0x7f7fffff61c0 "/anime/strtof"
output = 4.1461860541929491e-317
(gdb) step
14 if(argc < 2) {
(gdb) step
19 output = strtod(input, &endptr);
(gdb) until
20 if (input[0] == '\0' || *endptr != '\0') {
(gdb) info locals
endptr = 0x7f7fffff61cf ""
input = 0x7f7fffff61ce "0"
output = 0
(gdb) p input[0]
$1 = 48 '0'
(gdb) p *endptr
$2 = 0 '\0'
(gdb) step
24 (void)printf("%f\n", (float)output);
(gdb) info locals
endptr = 0x7f7fffff61cf ""
input = 0x7f7fffff61ce "0"
output = 0
(gdb)