Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > strtod usage for "just the number"?

Reply
Thread Tools

strtod usage for "just the number"?

 
 
David Mathog
Guest
Posts: n/a
 
      04-28-2011
The C string to double conversion functions all seem to operate on the
front of the input string, turning as much of it is as possible into a
number. In a situation where the string should be entirely the
number, and nothing should follow it, the best I have come up with to
handle this case is:

char *atoken;
char *to;
double dtmp;
/* lots of other stuff, generating atoken */
errno=0;
dtmp=strtod(atoken,&to);
if(errno || !to || *to != '\0'){
fprintf(stderr,"fatal error: incorrect number syntax
%s",atoken);
}

It works but isn't very pretty, what with 3 tests for the various
failure modes. Is there another way to go about this, more along the
lines of:

if(cvtS2D(atoken,&dtmp)){
}

?
Where the hypothetical conversion function returns 0 if the input
string is just a number, and something
else for all the other cases?

Thanks,

David Mathog
 
Reply With Quote
 
 
 
 
Fred
Guest
Posts: n/a
 
      04-28-2011
On Apr 28, 12:05*pm, David Mathog <(E-Mail Removed)> wrote:
> The C string to double conversion functions all seem to operate on the
> front of the input string, turning as much of it is as possible into a
> number. *In a situation where the string should be entirely the
> number, and nothing should follow it, the best I have come up with to
> handle this case is:
>
> char *atoken;
> char *to;
> double dtmp;
> * * * */* lots of other stuff, generating atoken */
> * * * * errno=0;
> * * * * dtmp=strtod(atoken,&to);
> * * * * if(errno || !to || *to != '\0'){
> * * * * * fprintf(stderr,"fatal error: incorrect number syntax
> %s",atoken);
> * * * * }
>
> It works but isn't very pretty, what with 3 tests for the various
> failure modes. *Is there another way to go about this, more along the
> lines of:
>
> * if(cvtS2D(atoken,&dtmp)){
> * }
>
> ?
> Where the hypothetical conversion function returns 0 if the input
> string is just a number, and something
> else for all the other cases?
>


strtod only sets errno if a range error occurred, so you do not need
that check to determine whether the field had bad characters in it.

You do not need the check (*to != '\0') since if 'to' is not NULL, it
points to the first unused character, which is guaranteed to be
something other than the NUL character.

That leaves you with:
if ( to ) { ... }
--
Fred K
 
Reply With Quote
 
 
 
 
David Resnick
Guest
Posts: n/a
 
      04-28-2011
On Apr 28, 3:05*pm, David Mathog <(E-Mail Removed)> wrote:
> The C string to double conversion functions all seem to operate on the
> front of the input string, turning as much of it is as possible into a
> number. *In a situation where the string should be entirely the
> number, and nothing should follow it, the best I have come up with to
> handle this case is:
>
> char *atoken;
> char *to;
> double dtmp;
> * * * */* lots of other stuff, generating atoken */
> * * * * errno=0;
> * * * * dtmp=strtod(atoken,&to);
> * * * * if(errno || !to || *to != '\0'){
> * * * * * fprintf(stderr,"fatal error: incorrect number syntax
> %s",atoken);
> * * * * }
>
> It works but isn't very pretty, what with 3 tests for the various
> failure modes. *Is there another way to go about this, more along the
> lines of:
>
> * if(cvtS2D(atoken,&dtmp)){
> * }
>
> ?
> Where the hypothetical conversion function returns 0 if the input
> string is just a number, and something
> else for all the other cases?
>


Why not just write your own function that does what the one above
does?
Lets you also control whether things that strtod will accept like
NAN or INFINITY or hex forms should count as "numbers".

-David
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      04-28-2011
Fred <(E-Mail Removed)> writes:

> On Apr 28, 12:05*pm, David Mathog <(E-Mail Removed)> wrote:
>> The C string to double conversion functions all seem to operate on the
>> front of the input string, turning as much of it is as possible into a
>> number. *In a situation where the string should be entirely the
>> number, and nothing should follow it, the best I have come up with to
>> handle this case is:
>>
>> char *atoken;
>> char *to;
>> double dtmp;
>> * * * */* lots of other stuff, generating atoken */
>> * * * * errno=0;
>> * * * * dtmp=strtod(atoken,&to);
>> * * * * if(errno || !to || *to != '\0'){
>> * * * * * fprintf(stderr,"fatal error: incorrect number syntax
>> %s",atoken);
>> * * * * }
>>
>> It works but isn't very pretty, what with 3 tests for the various
>> failure modes. *Is there another way to go about this, more along the
>> lines of:
>>
>> * if(cvtS2D(atoken,&dtmp)){
>> * }
>>
>> ?
>> Where the hypothetical conversion function returns 0 if the input
>> string is just a number, and something
>> else for all the other cases?
>>

>
> strtod only sets errno if a range error occurred, so you do not need
> that check to determine whether the field had bad characters in it.
>
> You do not need the check (*to != '\0') since if 'to' is not NULL, it
> points to the first unused character, which is guaranteed to be
> something other than the NUL character.
>
> That leaves you with:
> if ( to ) { ... }


I don't think that's right. If the programmer passes a valid pointer
as the second argument, it will get set to something -- either the value
of the first argument if no conversion could be done or to point just
past the converted data (even if that is a null byte).

As a result 'to == atoken || *to' is a sufficient test for failure in
this case.

--
Ben.
 
Reply With Quote
 
Fred
Guest
Posts: n/a
 
      04-28-2011
On Apr 28, 1:30*pm, Ben Bacarisse <(E-Mail Removed)> wrote:
> Fred <(E-Mail Removed)> writes:
> > On Apr 28, 12:05*pm, David Mathog <(E-Mail Removed)> wrote:
> >> The C string to double conversion functions all seem to operate on the
> >> front of the input string, turning as much of it is as possible into a
> >> number. *In a situation where the string should be entirely the
> >> number, and nothing should follow it, the best I have come up with to
> >> handle this case is:

>
> >> char *atoken;
> >> char *to;
> >> double dtmp;
> >> * * * */* lots of other stuff, generating atoken */
> >> * * * * errno=0;
> >> * * * * dtmp=strtod(atoken,&to);
> >> * * * * if(errno || !to || *to != '\0'){
> >> * * * * * fprintf(stderr,"fatal error: incorrect number syntax
> >> %s",atoken);
> >> * * * * }

>
> >> It works but isn't very pretty, what with 3 tests for the various
> >> failure modes. *Is there another way to go about this, more along the
> >> lines of:

>
> >> * if(cvtS2D(atoken,&dtmp)){
> >> * }

>
> >> ?
> >> Where the hypothetical conversion function returns 0 if the input
> >> string is just a number, and something
> >> else for all the other cases?

>
> > strtod only sets errno if a range error occurred, so you do not need
> > that check to determine whether the field had bad characters in it.

>
> > You do not need the check *(*to != '\0') since if 'to' is not NULL,it
> > points to the first unused character, which is guaranteed to be
> > something other than the NUL character.

>
> > That leaves you with:
> > * *if ( to ) { ... }

>
> I don't think that's right. *If the programmer passes a valid pointer
> as the second argument, it will get set to something -- either the value
> of the first argument if no conversion could be done or to point just
> past the converted data (even if that is a null byte).
>
> As a result 'to == atoken || *to' is a sufficient test for failure in
> this case.
>


You're right. The first test (to==token) is needed in case 'token'
is empty, in which case *to is '\0', so just checking *to is
not sufficient to test for failure.

--
Fred K
 
Reply With Quote
 
lawrence.jones@siemens.com
Guest
Posts: n/a
 
      04-28-2011
David Mathog <(E-Mail Removed)> wrote:
> The C string to double conversion functions all seem to operate on the
> front of the input string, turning as much of it is as possible into a
> number. In a situation where the string should be entirely the
> number, and nothing should follow it, the best I have come up with to
> handle this case is:
>
> char *atoken;
> char *to;
> double dtmp;
> /* lots of other stuff, generating atoken */
> errno=0;
> dtmp=strtod(atoken,&to);
> if(errno || !to || *to != '\0'){
> fprintf(stderr,"fatal error: incorrect number syntax %s",atoken);
> }


That isn't quite correct. strtod() will never set "to" to a null
pointer, but it will set it equal to atoken if no conversion could be
performed.

> It works but isn't very pretty, what with 3 tests for the various
> failure modes. Is there another way to go about this, more along the
> lines of:
>
> if(cvtS2D(atoken,&dtmp)){
> }


int cvtS2D(const char * restrict p, double * restrict d)
{
char *q;
errno = 0;
*d = strtod(p, &q);
return (errno != 0 || q == p || *q != '\0');
}
--
Larry Jones

It's going to be a long year. -- Calvin
 
Reply With Quote
 
katmac
Guest
Posts: n/a
 
      04-30-2011
On Apr 28, 3:05*pm, David Mathog <(E-Mail Removed)> wrote:
> The C string to double conversion functions all seem to operate on the
> front of the input string, turning as much of it is as possible into a
> number. *In a situation where the string should be entirely the
> number, and nothing should follow it, the best I have come up with to
> handle this case is:
>
> char *atoken;
> char *to;
> double dtmp;
> * * * */* lots of other stuff, generating atoken */
> * * * * errno=0;
> * * * * dtmp=strtod(atoken,&to);
> * * * * if(errno || !to || *to != '\0'){
> * * * * * fprintf(stderr,"fatal error: incorrect number syntax
> %s",atoken);
> * * * * }
>
> It works but isn't very pretty, what with 3 tests for the various
> failure modes. *Is there another way to go about this, more along the
> lines of:
>
> * if(cvtS2D(atoken,&dtmp)){
> * }
>
> ?
> Where the hypothetical conversion function returns 0 if the input
> string is just a number, and something
> else for all the other cases?
>
> Thanks,
>
> David Mathog


char junk;
return !(sscanf( atoken, "%lf%c", dtmp, &junk ) == 1);

The same pattern can be used for anything sscanf can decode (which is
quite a lot)

 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      04-30-2011
On Thu, 2011-04-28, David Mathog wrote:
> The C string to double conversion functions all seem to operate on the
> front of the input string, turning as much of it is as possible into a
> number. In a situation where the string should be entirely the
> number, and nothing should follow it, the best I have come up with to
> handle this case is:

....
> It works but isn't very pretty, what with 3 tests for the various
> failure modes. Is there another way to go about this, more along the
> lines of:
>
> if(cvtS2D(atoken,&dtmp)){
> }


With these functions I tend to prefer returning the value and
passing a pointer to an errno-like error:

double cvtS2D(const char* buf, int* error);

int err = 0;
const double foo = cvsS2D(buf, &err);
const double bar = cvsS2D(buf2, &err);
if(err) // at least one input was broken

Although tastes (and usage patterns) vary.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-30-2011
katmac <(E-Mail Removed)> writes:
> On Apr 28, 3:05*pm, David Mathog <(E-Mail Removed)> wrote:
>> The C string to double conversion functions all seem to operate on the
>> front of the input string, turning as much of it is as possible into a
>> number. *In a situation where the string should be entirely the
>> number, and nothing should follow it, the best I have come up with to
>> handle this case is:
>>
>> char *atoken;
>> char *to;
>> double dtmp;
>> * * * */* lots of other stuff, generating atoken */
>> * * * * errno=0;
>> * * * * dtmp=strtod(atoken,&to);
>> * * * * if(errno || !to || *to != '\0'){
>> * * * * * fprintf(stderr,"fatal error: incorrect number syntax
>> %s",atoken);
>> * * * * }
>>
>> It works but isn't very pretty, what with 3 tests for the various
>> failure modes. *Is there another way to go about this, more along the
>> lines of:
>>
>> * if(cvtS2D(atoken,&dtmp)){
>> * }
>>
>> ?
>> Where the hypothetical conversion function returns 0 if the input
>> string is just a number, and something
>> else for all the other cases?

>
> char junk;
> return !(sscanf( atoken, "%lf%c", dtmp, &junk ) == 1);
>
> The same pattern can be used for anything sscanf can decode (which is
> quite a lot)


Unfortunately, if the string being scanned represents a number
outside the range of the target type, the behavior of sscanf is
undefined. See C99 7.19.6.2p10 (it's split across pages in n1256).

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
David Mathog
Guest
Posts: n/a
 
      05-02-2011
On Apr 30, 7:01*am, Jorgen Grahn <(E-Mail Removed)> wrote:
> On Thu, 2011-04-28, David Mathog wrote:
>
> > * if(cvtS2D(atoken,&dtmp)){
> > * }

>
> With these functions I tend to prefer returning the value and
> passing a pointer to an errno-like error:
>
> * *double cvtS2D(const char* buf, int* error);
>
> * *int err = 0;
> * *const double foo = cvsS2D(buf, &err);
> * *const double bar = cvsS2D(buf2, &err);
> * *if(err) // at least one input was broken
>
> Although tastes (and usage patterns) vary.


Right, styles vary. I would have done that like:

if(!cvtS2D(buf1,&dtmp1)){ boom("message1"); }
if(!cvtS2D(buf2,&dtmp2)){ boom("message2"); }

Either way, the important part is that the function returns ONE
unambiguous status value, which I think is better than having to check
multiple values to see if there was a problem or not. There are a lot
of C functions that follow the second path, including and especially
all those that depend on errno,
where one must look at one value for "the operation did not work (or
maybe it did but this might be a special case)" and another value for
"the problem was (or wasn't) ...". For instance, fscanf returning
EOF.

Regards,

David Mathog

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Aliasing/Torek's strtod() experience Adam Warner C Programming 9 07-13-2005 10:48 PM
Aliasing/Torek's strtod() experience Adam Warner C Programming 0 06-29-2005 01:23 AM
strtod / setlocale Mathieu Malaterre C++ 1 12-13-2004 06:24 PM
std::string and strtod() Leslaw Bieniasz C++ 3 09-21-2004 07:22 AM
strtod - Dynamic Memory? Marky C C Programming 20 04-04-2004 12:21 AM



Advertisments