|
From: Per W. <pw...@ia...> - 2003-01-19 20:47:18
|
Hello!
Don't use atof() for converting from text string to a double.
Use strtod() instead, since it will inform you how many characters it
consumed.
char mystring[] =3D "1.2E-3*3";
char *p =3D mystring;
char *end;
num =3D strtod(p,&end);
Now end will point to the '*' character, since '1.2E-3' is consumed and
returned as the double 0.0012.
Note also when parsing infix expressions, that you normally have to take
care of unary signs, i.e. 1+-2 which should be evaluated as 1 + (-2).
Easiest is to perform the parsing with a recursive-descent parser, i.e.
something like:
eval_expr()
return eval_additive()
eval_additive()
while (*p =3D=3D '+' || *p =3D=3D '-')
if (*p =3D=3D '+') {
p++;
n +=3D eval_multiplicative()
} else {
p++;
n -=3D eval_multiplicative()
}
return n;
eval_multiplicative()
n =3D eval_factor()
while (*p =3D=3D '*' || *p =3D=3D '/')
if (*p =3D=3D '*') {
p++;
n *=3D eval_factor();
} else {
p++;
n /=3D eval_factor();
}
return n;
eval_factor()
if (*p =3D=3D =B4+') {p++; return eval_factor(); }
if (*p =3D=3D '-') {p++; return -eval_factor(); }
if (*p =3D=3D '(') {p++; n =3D eval_expr(); if (p !=3D ')') error(); retu=
rn n; }
return number();
Good luck!
/Per W
On Sun, 19 Jan 2003, j b wrote:
>
>
>
> ---------------------------------
> Gesendet von http://mail.yahoo.de.
> Bis zu 100 MB Speicher bei http://premiummail.yahoo.de.
|
|
From: Ioannis V. <no...@ho...> - 2003-01-28 01:16:57
|
------Original Message-------=0D =0D From: Per Westermark=0D Date: Sunday, 19 January 2003 10:48:26 PM=0D To: j b=0D Cc: dev...@li...=0D Subject: Re: [Dev-C++] atof 2...=0D =0D Hello!=0D =0D Don't use atof() for converting from text string to a double.=0D =0D Use strtod() instead, since it will inform you how many characters it=0D consumed.=0D =0D =0D =0D =3D=3D> What about sscanf()?=0D =0D =0D =0D Ioannis Vranos=0D =0D * Programming pages: http://www.noicys.freeurl.com=0D * Alternative URL: http://run.to/noicys=20 |
|
From: Per W. <pw...@ia...> - 2003-01-28 08:42:11
|
sscanf can convert one or multiplie parameters from a text string into corresponding variables. The problem is that you have very little control of what sscanf considers white characters etc. And in case of a conversion problem, it isn't easy to point exactly at the failing character. With strtod, you get a pointer to the first un-processed character of your input string. For a parser, the normal action is to process characters one at a time - that means that strotod is never called unless the parser knows that the first character is the start of a number, i.e. the next character to process is 0-9 or a decimal separator (. or , depending on locale). Uppon return of atrtod, the parser may then immediately continue parsing at the endptr position. /Per W On Sun, 19 Jan 2003, Ioannis Vranos wrote: > ------Original Message------- > > From: Per Westermark > Date: Sunday, 19 January 2003 10:48:26 PM > To: j b > Cc: dev...@li... > Subject: Re: [Dev-C++] atof 2... > > Hello! > > Don't use atof() for converting from text string to a double. > > Use strtod() instead, since it will inform you how many characters it > consumed. > > > > ==> What about sscanf()? > > > > Ioannis Vranos > > * Programming pages: http://www.noicys.freeurl.com > * Alternative URL: http://run.to/noicys |
|
From: Ioannis V. <no...@ho...> - 2003-01-28 09:18:27
|
-------Original Message-------=0D =0D From: Per Westermark=0D Date: =D4=F1=DF=F4=E7, 28 =C9=E1=ED=EF=F5=DC=F1=E9=EF=F2 2003 10:43:25 =F0= =EC=0D To: Ioannis Vranos=0D Cc: dev...@li...=0D Subject: Re: [Dev-C++] atof 2...=0D =0D sscanf can convert one or multiplie parameters from a text string into=0D corresponding variables. The problem is that you have very little control= =0D of what sscanf considers white characters etc. And in case of a conversio= n=0D problem, it isn't easy to point exactly at the failing character.=0D =0D With strtod, you get a pointer to the first un-processed character of you= r=0D input string. For a parser, the normal action is to process characters on= e=0D at a time - that means that strotod is never called unless the parser=0D knows that the first character is the start of a number, i.e. the next=0D character to process is 0-9 or a decimal separator (. or , depending=0D on locale). Uppon return of atrtod, the parser may then immediately=0D continue parsing at the endptr position.=0D =0D /Per W=0D =0D =0D =3D=3D> Yes it's a nice for-double-only valid way too. But i prefer sscan= f() for all this kind of stuff. :)=0D =0D =0D Ioannis Vranos=0D =0D * Programming pages: http://www.noicys.freeurl.com=0D * Alternative URL: http://run.to/noicys=20 |
|
From: Per W. <pw...@ia...> - 2003-01-28 09:55:59
|
Just as long as you are aware that strtod, strtof, strtol, ... can perform tricks that sscanf can not. sscanf works reasonable for processing a configuration file with known contents. It doesn't work when parsing a language, or an expression, since you don't know the contents of the line until you have parsed it. /Per W On Tue, 28 Jan 2003, Ioannis Vranos wrote: > -------Original Message------- > > From: Per Westermark > Date: =D4=F1=DF=F4=E7, 28 =C9=E1=ED=EF=F5=DC=F1=E9=EF=F2 2003 10:43:25 = =F0=EC > To: Ioannis Vranos > Cc: dev...@li... > Subject: Re: [Dev-C++] atof 2... > > sscanf can convert one or multiplie parameters from a text string into > corresponding variables. The problem is that you have very little control > of what sscanf considers white characters etc. And in case of a conversio= n > problem, it isn't easy to point exactly at the failing character. > > With strtod, you get a pointer to the first un-processed character of you= r > input string. For a parser, the normal action is to process characters on= e > at a time - that means that strotod is never called unless the parser > knows that the first character is the start of a number, i.e. the next > character to process is 0-9 or a decimal separator (. or , depending > on locale). Uppon return of atrtod, the parser may then immediately > continue parsing at the endptr position. > > /Per W > > > =3D=3D> Yes it's a nice for-double-only valid way too. But i prefer sscan= f() for > all this kind of stuff. :) > > > Ioannis Vranos > > * Programming pages: http://www.noicys.freeurl.com > * Alternative URL: http://run.to/noicys |