Toon posts:

[C] atof(const char *nptr)

Pagina: 1
Acties:
  • 109 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
in heb een pointer genaamd "pntr" met de string "100.00", ik wil deze converteren naar een float. Als ik de volgende code geef "amount = atof(pntr);", dan heeft amount de waarde 0.00

Ik begrijp het echt niet.


ps. amount is gedeclareerd als float.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

weet je zeker dat het "100.00" is? Staat er niet per ongeluk een spatie voor? Test het zo eens:

C:
1
2
float f = atof ("100.00");
printf ("%f\n", f);

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • LazySod
  • Registratie: Augustus 2003
  • Laatst online: 23-05 18:32

LazySod

Scumbag with a mission

Verwijderd schreef op 16 april 2004 @ 12:42:
in heb een pointer genaamd "pntr" met de string "100.00", ik wil deze converteren naar een float. Als ik de volgende code geef "amount = atof(pntr);", dan heeft amount de waarde 0.00

Ik begrijp het echt niet.


ps. amount is gedeclareerd als float.
post eens een clipping van je code waar je ziet dat het fout gaat.. hier (op een Alpha, gebruik makende van een VMS C++ compiler) werkt het naar behoren.

Proof is the idol before whom the pure mathematician tortures himself. (Sir Arthur Eddington)


Verwijderd

Topicstarter
float f;
f = atof("120");
printf("f: %f\n",f);


output:
f: 0.000000


Dus atof() werkt gewoon niet, atoi() daarentegen werkt wel, maar omdat het om bedragen gaat, kan ik die helaas niet gebruiken.

  • Dawai
  • Registratie: December 2000
  • Laatst online: 26-05 01:27

Dawai

HERiTAGE CHESS CREW

Verwijderd schreef op 16 april 2004 @ 15:43:
float f;
f = atof("120");
printf("f: %f\n",f);
Werkt hier... Welke compiler gebruik je? Geen compiler warnings?

[ Voor 11% gewijzigd door Dawai op 16-04-2004 15:49 ]

Programmer: red-eyed, mumbling mammal capable of conversing with inanimate objects.


Verwijderd

Topicstarter
Dawai schreef op 16 april 2004 @ 15:48:
[...]

Werkt hier... Welke compiler gebruik je? Geen compiler warnings?
geen warnings.
ik gebruik gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

Verwijderd

Allereerst, terug van lang weggeweest (ik was flink ziek), hoi allemaal.

Ik gebruik een identieke compilerversie (upgraded RedHat 9) en heb deze fout niet; er is schijnbaar iets fout gegaan tijdens het upgraden/installeren vd. compiler; of je hebt ergens een eigen atof() in je code gedefinieerd die altijd 0.0 retourneert.

Probeer eens strtod() in plaats van atof()? (strtod() is een ANSI C functie, atof() niet; strtod() is dus sowieso meer portable).

  • _Squatt_
  • Registratie: Oktober 2000
  • Niet online
Je vergeet om stdlib.h te includen. Nu gaat gcc ervan uit dat atof gedeclareert is als:
C:
1
extern int atof()

Maar atof() returnt een double.

Als ik compile met -Wall krijg ik overigens wel een warning (met gcc 3.3.2):
code:
1
2
3
$ gcc -Wall test.c
test.c: In function `main':
test.c:7: warning: implicit declaration of function `atof'

"He took a duck in the face at two hundred and fifty knots."


Verwijderd

Topicstarter
[ quote]_Squatt_ schreef op 16 april 2004 @ 16:27:
Je vergeet om stdlib.h te includen.
[/code]

dank je wel! Ik was inderdaad vergeten om stdlib.h te includen. 8)7

[ Voor 48% gewijzigd door Verwijderd op 16-04-2004 16:40 ]


  • Dawai
  • Registratie: December 2000
  • Laatst online: 26-05 01:27

Dawai

HERiTAGE CHESS CREW

Hmm, stom dat gcc dan standaard geen warning geeft.

code:
1
2
3
$ gcc -o atof -s atof.c
$ ./atof
f: 67328.000000

cc geeft wel een warning:

code:
1
2
3
4
$ cc -o atof -s atof.c
"atof.c", line 5: warning: implicit function declaration: atof
$ ./atof
f: 133216.000000

:P

En met -Wall krijg je er ook een met gcc:

code:
1
2
3
$ gcc -Wall -o atof -s atof.c
atof.c: In function `main':
atof.c:5: warning: implicit declaration of function `atof'

[ Voor 4% gewijzigd door Dawai op 16-04-2004 16:55 ]

Programmer: red-eyed, mumbling mammal capable of conversing with inanimate objects.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 16 april 2004 @ 16:16:
Probeer eens strtod() in plaats van atof()? (strtod() is een ANSI C functie, atof() niet; strtod() is dus sowieso meer portable).
Welkom terug :w
atof is wel degelijk een ANSI C functie hoor

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Dawai schreef op 16 april 2004 @ 16:49:
Hmm, stom dat gcc dan standaard geen warning geeft.
Als je gewoon C++ gebruikt in plaats van C heb je dit soort 'stomme' foutjes niet.

Verwijderd

Hey, ouwe slotenmaker ;)
atof is wel degelijk een ANSI C functie hoor
Kweetniet, mijn docs zeggen van niet (conforming to SVID 3, POSIX, BSD 4.3, ISO 9899), maar ISO 9899 zal ondertussen wel door elke zichzelf respecterende compiler ondersteund worden.
OlafvdSpek schreef op 16 april 2004 @ 19:33:
Als je gewoon C++ gebruikt in plaats van C heb je dit soort 'stomme' foutjes niet.
Dat is lichtelijk gevaarlijk, C en C++ zijn niet 100% syntax-compatible meer (de trenaire operator ("... ? ... : ...") werkt bv. anders). Ik persoonlijk compileer alle C met "gcc -ansi -pedantic -Wall -Werror" (of nog meer -Wxxx flags).

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 16 april 2004 @ 20:09:
Dat is lichtelijk gevaarlijk, C en C++ zijn niet 100% syntax-compatible meer (de trenaire operator ("... ? ... : ...") werkt bv. anders). Ik persoonlijk compileer alle C met "gcc -ansi -pedantic -Wall -Werror" (of nog meer -Wxxx flags).
Hmm, wat hebben ze daar nou weer mee gedaan dan?

[ Voor 5% gewijzigd door Olaf van der Spek op 16-04-2004 20:22 ]


Verwijderd

OlafvdSpek schreef op 16 april 2004 @ 20:22:
Hmm, wat hebben ze daar nou weer mee gedaan dan?
De precedence van assignment aan een trenaire operator is veranderd:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main(void)
{
    int x= 0;
    int y= 2;
    int c;
    for(c= 0; c < 2; ++c) {
        c ? y : x = c + 3;
        printf("%i %i\n", x, y);
    }
    return 0;
}

C output:
3 2
3 4
C++ output:
3 2
3 2
Dit is een erg obscure, hij wordt zelfs hier niet vermeld.

edit:
Ik zie nu dat ik in de vorige post syntax-incompatible schrijf, dat klopt natuurlijk niet, dit is een semantisch verschil (de zelfde code wordt wel door beide compilers geaccepteerd, maar produceert verschillende resultaten).

[ Voor 28% gewijzigd door Verwijderd op 17-04-2004 03:06 . Reden: toevoeging ]


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 15:28

Robtimus

me Robtimus no like you

Verwijderd schreef op 17 april 2004 @ 02:34:
[...]

De precedence van assignment aan een trenaire operator is veranderd:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main(void)
{
    int x= 0;
    int y= 2;
    int c;
    for(c= 0; c < 2; ++c) {
        c ? y : x = c + 3;
        printf("%i %i\n", x, y);
    }
    return 0;
}

C output:

[...]

C++ output:

[...]


Dit is een erg obscure, hij wordt zelfs hier niet vermeld.

edit:
Ik zie nu dat ik in de vorige post syntax-incompatible schrijf, dat klopt natuurlijk niet, dit is een semantisch verschil (de zelfde code wordt wel door beide compilers geaccepteerd, maar produceert verschillende resultaten).
Welke compiler gebruik jij? Ik gebruik gcc 2.96, en krijg als eerste output 3 0 ipv 3 2. Met C++ krijg ik 2x 3 0.y op 0 geinitialiseerd |:(

Als je trouwens -pedantic als optie geeft dan krijg je een waarschuwing als je het als C compiled: "ISO C forbids use of conditional expression as lvalues"

[ Voor 5% gewijzigd door Robtimus op 17-04-2004 12:04 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

Verwijderd schreef op 16 april 2004 @ 12:42:
in heb een pointer genaamd "pntr" met de string "100.00", ik wil deze converteren naar een float. Als ik de volgende code geef "amount = atof(pntr);", dan heeft amount de waarde 0.00
atoi(), atof() en de rest van de familie zijn oerlelijk : Je kan niet zien of een conversie goed gaat of niet. Ik zou de atof() even vervangen door een strtod(), dan kan je op errors checken. Hier gaat het overigens wel goed (ik krijg d'r 100.0000 uit).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 16 april 2004 @ 20:09:
Kweetniet, mijn docs zeggen van niet (conforming to SVID 3, POSIX, BSD 4.3, ISO 9899), maar ISO 9899 zal ondertussen wel door elke zichzelf respecterende compiler ondersteund worden.
wat zijn die docs dan? Google maar eens: [google=ansi c library reference], atof wordt altijd wel genoemd. Het is wel degelijk een ANSI C iets, en ook niet specifiek C99

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn schreef op 19 april 2004 @ 17:47:
wat zijn die docs dan? Google maar eens: [google=ansi c library reference], atof wordt altijd wel genoemd. Het is wel degelijk een ANSI C iets, en ook niet specifiek C99
Mijn docs zijn de man en info pages van mijn systeem :)

Het probleem bij dit soort discussies: ISO 9899 an sich bestaat niet, je hebt enerzijds ANSI C (ISO/EIC 9899-1989), ook wel C89 genoemd; en anderzijds ISO C (ISO/EIC 9899-1990), ook wel C90 genoemd. Een heleboel manuals husselen dit door elkaar; *nix manpages zijn vrij naukeurig in het onderscheid en schrijven meestal "ANSI C" voor C89 en "ISO 9899" voor C90.

Het kan best zijn dat die manpage niet klopt, (vandaar die kweetniet), no big deal :)

edit:
(En dan heb je natuurlijk ook nog ISO/EIC 9899-1999 oftewel C99, maar daar ging het niet over)

[ Voor 8% gewijzigd door Verwijderd op 19-04-2004 23:18 . Reden: toevoeging ]


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 15:28

Robtimus

me Robtimus no like you

strtod is idd the way to go:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// errno.h included
char *s = "100.00";
char *end = NULL;
double val;

errno = 0;
val = strtod(s, &end);
if (end == s) // geen getal
if (val == HUGE_VAL)
{
    if (errno == ERANGE)
        // te groot getal
    else // val is gewoon "toevallig" het maximum
}
// eventueel:
if (end != NULL) // er zit iets achter het getal

[ Voor 5% gewijzigd door Robtimus op 20-04-2004 10:15 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

IceManX schreef op 20 april 2004 @ 10:11:
// eventueel:
if (end != NULL) // er zit iets achter het getal[/code]
Dit is niet correct : Met heeft het expliciet over de inhoud van **endptr, en die moet '\0' zijn. Da's wat anders als NULL.

MAW : in de bovenstaande code moet de conditie :

code:
1
if (*end != '\0') //


zijn.

[ Voor 5% gewijzigd door igmar op 20-04-2004 11:41 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
igmar schreef op 20 april 2004 @ 11:41:
[...]


Dit is niet correct : Met heeft het expliciet over de inhoud van **endptr, en die moet '\0' zijn. Da's wat anders als NULL.

MAW : in de bovenstaande code moet de conditie :

code:
1
if (*end != '\0') //


zijn.
0, '\0' en NULL zijn toch allemaal 0 'achter de schermen'?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:14
Zoals gezegd is NULL in C meestal ((void*)0) (hoewel dat effectief ook 0 is) en dan krijg je een lelijke vergelijking tussen char en void*. Het mooiste vind ik dan om met '\0' te vergelijken, omdat dan direct duidelijk is dat je karakters aan het vergelijken bent. Echt uitmaken doet het niet, want semantisch worden beide argumenten toch eerst geconverteerd naar integers voordat ze vergeleken worden.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Ik schrijf altijd gewoon:
C++:
1
if (*end)

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 15:28

Robtimus

me Robtimus no like you

igmar schreef op 20 april 2004 @ 11:41:
[...]


Dit is niet correct : Met heeft het expliciet over de inhoud van **endptr, en die moet '\0' zijn. Da's wat anders als NULL.

MAW : in de bovenstaande code moet de conditie :

code:
1
if (*end != '\0') //


zijn.
Heb je volledig gelijk in. Ik heb het alleen pas NA het posten getest, en kwam er toen idd achter. De man pages hebben het alleen wel fout, want die hebben het over NULL:
RETURN VALUE
These functions return the converted value, if any.

If endptr is not NULL, a pointer to the character after the last character used in the conversion is stored in the location referenced by endptr.

If no conversion is performed, zero is returned and the value of nptr is stored in the location referenced by endptr.

If the correct value would cause overflow, plus or minus HUGE_VAL (HUGE_VALF, HUGE_VALL) is returned (according to the sign of the value), and ERANGE is stored in errno. If the correct value would cause underflow, zero is returned and ERANGE is stored in errno.

ERRORS
ERANGE Overflow or underflow occurred.
Wanneer is endptr dan ooit NULL??
OlafvdSpek schreef op 20 april 2004 @ 17:07:
Ik schrijf altijd gewoon:
C++:
1
if (*end)
Da's wel de makkelijkste oplossing ja :)

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:14
IceManX schreef op 20 april 2004 @ 18:24:
Wanneer is endptr dan ooit NULL??
Als jij NULL meegeeft! Je mag strtod dus best zo gebruiken, als het je niet ïnteresseerd in hoeverre de hele string geparsed is:
C:
1
double foo = strtod("1234", NULL);

Als endptr niet NULL is, dan doet de functie een assignment aan *endptr en die zal dan nooit NULL zijn, hoewel **endptr natuurlijk wel '\0' kan zijn. ;)

  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

IceManX schreef op 20 april 2004 @ 18:24:
Wanneer is endptr dan ooit NULL??
Als je d'r NULL instopt. In dat geval is het gelijk aan atof(). **endptr is gelijk aan het karakter waarop de conversie fout gaat, en is \0 als het goed is (aka eind van de string). De manual van strtol() is hierover overigens een stuk duidelijker.
code:
1
    if (*end)

Da's wel de makkelijkste oplossing ja
Kwestie van stijl, het zal de compiler iig weinig uitmaken.
Pagina: 1