how can i Know whether atoi function call succeed?

  • Thread starter Anonymousgoogledeja
  • Start date
A

Anonymousgoogledeja

Hi all,


since the function atof, atoi, _atoi64, atol returned value are

Return Values

Each function returns the double, int, __int64 or long value produced
by interpreting the input characters as a number. The return value is 0
(for atoi and _atoi64), 0L (for atol), or 0.0 (for atof) if the input
cannot be converted to a value of that type. The return value is
undefined in case of overflow.

how can I tell if these function calls fail or succeed?


thanks.

Baumann@Pan
 
R

Robert Gamble

Anonymousgoogledeja said:
Hi all,


since the function atof, atoi, _atoi64, atol returned value are

Return Values

Each function returns the double, int, __int64 or long value produced
by interpreting the input characters as a number. The return value is 0
(for atoi and _atoi64), 0L (for atol), or 0.0 (for atof) if the input
cannot be converted to a value of that type. The return value is
undefined in case of overflow.

how can I tell if these function calls fail or succeed?

_atoi64 is not a standard function but for the rest, you cannot
portably tell if they succeed or fail. Some systems may set errno on
failure but this is not required. This is a good reason to use strto*
functions instead.

Robert Gamble
 
J

Jack Klein

On 21 Aug 2005 19:55:47 -0700, "Anonymousgoogledeja"

Amazing, you actually printed part of the documentation yet you missed
the most important point!
Hi all,


since the function atof, atoi, _atoi64, atol returned value are

Return Values

Each function returns the double, int, __int64 or long value produced
by interpreting the input characters as a number. The return value is 0
(for atoi and _atoi64), 0L (for atol), or 0.0 (for atof) if the input
cannot be converted to a value of that type. The return value is
^^^^^^^^^^^^^^^^^^^
undefined in case of overflow.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
how can I tell if these function calls fail or succeed?

Actually the text you quoted it not quite correct. If you call one of
the ato... functions and the converted value is outside the range of
the destination type, the behavior is undefined, not just the return
value. That means, according to the C standard, any of the usual and
nasty symptoms of undefined behavior can happen: reformatting your
hard drive, causing demons to fly out of your nose, causing your
operating system to display a sarcastic message to the user and
terminate your program... The list of possibilities is endless.

The best way to use the ato... functions is to completely omit them
from your program. Unless you pre-check the string to verify that the
result will be in range, in which case you might as well do the
conversion at the same time.

Instead, use the much safer strto... functions prototyped <stdlib.h>
which have defined behavior no matter what the input looks like, so
long as it is not a null pointer. If you pass a valid second pointer
value, you can even tell if a result of 0 is caused by an input of
"0", or by not having anything to convert.

Look at the sample code here:

http://www.jk-technology.com/c/code/strtol.html
 
A

Anonymousgoogledeja

Robert said:
_atoi64 is not a standard function but for the rest, you cannot
portably tell if they succeed or fail. Some systems may set errno on
failure but this is not required. This is a good reason to use strto*
functions instead.

Robert Gamble


what's underflow? i can figure out what overflow is.

what about the return value of strtoul('0',0,10)? how can i know if the
returned value 0 is the converted or because there is an error while
converting.

thanks
 
P

Peter Nilsson

Jack said:
<snip>
...
Look at the sample code here:

http://www.jk-technology.com/c/code/strtol.html

[From the page...]
for ( ; ; )
{
printf("Enter an int, return only to quit: ");
fflush(stdout);
fgets(buff, sizeof buff, stdin);

You should check the return value of fgets() here.
if (buff [0] == '\n')
{
break;
}
/* here is where you might want to add code to */
/* test for extra non-numeric characters at the */
/* end of the input string, if you want that to */
/* be an error */
/* */
/* if you want to generate this error, remove */
/* the two preprocessor lines that start with */
/* #if 0 and #endif */

#if 0

If I change this to 1, the code below will issue a misleading message
(from the point of view of a typical end user) since fgets() generally
leaves a trailing new-line.
 
M

Michael Mair

Anonymousgoogledeja said:
what's underflow? i can figure out what overflow is.

STFW:
said:
what about the return value of strtoul('0',0,10)? how can i know if the
returned value 0 is the converted or because there is an error while
converting.

That is the point about reading and trying to understand documentation:
So that you know how to use something (or that you are able to ask
clever questions).

ret = strtoul('0',0,10);
will not even compile.

ret = strtoul("0",0,10);
gives you no chance whatsoever to find out whether you got a zero
or an error. Use this only if you cannot have zero input values.

char *p, *q = "0";
ret = strtoul(q, &p, 10);
gives you the chance to check for errors on zero:
if (ret == 0 && p == q) {
/* error */
}
Moreover, you can check for overflow
else if (ret == ULONG_MAX && errno == ERANGE) {
/* error */
}
This means that you have to #include <errno.h>, of course.


Cheers
Michael
 
R

Robert Gamble

Anonymousgoogledeja said:
what's underflow? i can figure out what overflow is.

Underflow occurs when the result is too small to be stored in the
designated type (FLT_MIN/2 for a float for instance), overflow occurs
when the result is too large to be stored in the designated type (for
example INT_MAX+1 for an int).
what about the return value of strtoul('0',0,10)? how can i know if the
returned value 0 is the converted or because there is an error while
converting.

The first argument to strtoul must be a pointer to char, '0' is an
integer (character constants are integers in C), you must mean
strtoul("0", 0, 10). If strtoul returns 0 you know that either the
result of the conversion was 0 or that no conversion could be
performed. In this particular example you cannot portably tell the
difference, some implementations set errno to EINVAL in this case but
this is not required, the Standard doesn't even define EINVAL. If you
had provided a valid non-null value as the second argument to strtoul
you would be able to recognize the lack of conversion as the value
stored in the pointer whose address you provided would be set to the
value of the first argument.

For example:

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

int main (void) {
unsigned long ul;
char * nptr = "invalid";
char * endptr;
ul = strtoul(nptr, &endptr, 10);
if (ul == 0 && nptr == endptr) {
printf("No conversion occured\n");
}
return 0;
}

Note that if nptr==endptr then ul will always be 0 so the first part of
the test is superfluous.

The documentation that came with your implementation should cover all
of this, please refer to it before asking your next question.

Robert Gamble
 
M

Michael Mair

Robert said:
Underflow occurs when the result is too small to be stored in the
designated type (FLT_MIN/2 for a float for instance), overflow occurs
^^^^^^^^^
FLT_MIN is the minimum normalized float >0. You can have every number
down to FLT_MIN*FLT_EPSILON, so a better example is
FLT_MIN*FLT_EPSILON/2
when the result is too large to be stored in the designated type (for
example INT_MAX+1 for an int).

<rest snipped>

Cheers
Michael
 
A

Anonymousgoogledeja

Robert said:
Underflow occurs when the result is too small to be stored in the
designated type (FLT_MIN/2 for a float for instance), overflow occurs
when the result is too large to be stored in the designated type (for
example INT_MAX+1 for an int).


The first argument to strtoul must be a pointer to char, '0' is an
integer (character constants are integers in C), you must mean
strtoul("0", 0, 10). If strtoul returns 0 you know that either the
result of the conversion was 0 or that no conversion could be
performed. In this particular example you cannot portably tell the
difference, some implementations set errno to EINVAL in this case but
this is not required, the Standard doesn't even define EINVAL. If you
had provided a valid non-null value as the second argument to strtoul
you would be able to recognize the lack of conversion as the value
stored in the pointer whose address you provided would be set to the
value of the first argument.

For example:

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

int main (void) {
unsigned long ul;
char * nptr = "invalid";
char * endptr;
ul = strtoul(nptr, &endptr, 10);
if (ul == 0 && nptr == endptr) {
printf("No conversion occured\n");
}
return 0;
}

Note that if nptr==endptr then ul will always be 0 so the first part of
the test is superfluous.

The documentation that came with your implementation should cover all
of this, please refer to it before asking your next question.

Robert Gamble


thanks, compare the endptr & nptr is the good way to know more about
the returned value 0 .
 
C

CBFalconer

Michael said:
^^^^^^^^^
FLT_MIN is the minimum normalized float >0. You can have every number
down to FLT_MIN*FLT_EPSILON, so a better example is
FLT_MIN*FLT_EPSILON/2

Only if the real arithmetic system implements gradual underflow,
which is not mandated by the C standard, although it is by the IEEE
float standard.
 
A

Alan Balmer

Hi all,


since the function atof, atoi, _atoi64, atol returned value are

Return Values

Each function returns the double, int, __int64 or long value produced
by interpreting the input characters as a number. The return value is 0
(for atoi and _atoi64), 0L (for atol), or 0.0 (for atof) if the input
cannot be converted to a value of that type. The return value is
undefined in case of overflow.

how can I tell if these function calls fail or succeed?
You can't. Look at the strtol function instead. It returns a pointer
to the first character not converted, and sets errno if no conversion
can be performed.
 
R

Robert Gamble

Michael said:
^^^^^^^^^
FLT_MIN is the minimum normalized float >0. You can have every number
down to FLT_MIN*FLT_EPSILON, so a better example is
FLT_MIN*FLT_EPSILON/2

As Chuck pointed out, this only applies to systems that support gradual
underflow which is not required by the Standard. Many systems do
support this though and it wouldn't have hurt to preface my statement
with "on implementations that do not support subnormal floating-point
numbers...", thanks for the clarification.

Robert Gamble
 
T

tedu

Michael said:
char *p, *q = "0";
ret = strtoul(q, &p, 10);
gives you the chance to check for errors on zero:
if (ret == 0 && p == q) {
/* error */
}
Moreover, you can check for overflow
else if (ret == ULONG_MAX && errno == ERANGE) {
/* error */
}
This means that you have to #include <errno.h>, of course.

You also need to initialize errno to 0 (or at least not ERANGE) in
order to tell if it was this call to strtoul that failed.
 
M

Michael Mair

CBFalconer said:
... snip ...


Only if the real arithmetic system implements gradual underflow,
which is not mandated by the C standard, although it is by the IEEE
float standard.

True. Thanks for the enlightenment :)
Michael
 
J

Jack Klein

Jack said:
<snip>
...
Look at the sample code here:

http://www.jk-technology.com/c/code/strtol.html

[From the page...]
for ( ; ; )
{
printf("Enter an int, return only to quit: ");
fflush(stdout);
fgets(buff, sizeof buff, stdin);

You should check the return value of fgets() here.
if (buff [0] == '\n')
{
break;
}
/* here is where you might want to add code to */
/* test for extra non-numeric characters at the */
/* end of the input string, if you want that to */
/* be an error */
/* */
/* if you want to generate this error, remove */
/* the two preprocessor lines that start with */
/* #if 0 and #endif */

#if 0

If I change this to 1, the code below will issue a misleading message
(from the point of view of a typical end user) since fgets() generally
leaves a trailing new-line.
else if ('\0' != *end_ptr)
{
printf("extra characters on input line\n");
}
#endif

Thanks pointing out these issues. I have updated the page.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top