Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strtol using errno

Tags:

c

c89

I have the following code:

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

void main(void)
{
     int data;
     char * tmp;
     data = strtol("23ef23",&tmp,10);
     printf("%d",errno);
     getchar();
}

output is 0 ...

why?

i am using visual studio 2010 C++ code must be C89 compatible.

like image 784
Nahum Avatar asked Dec 05 '25 04:12

Nahum


2 Answers

strtol only sets errno for overflow conditions, not to indicate parsing failures. For that purpose, you have to check the value of the end pointer, but you need to store a pointer to the original string:

char const * const str = "blah";
char const * endptr;

int n = strtol(str, &endptr, 0);

if (endptr == str) { /* no conversion was performed */ }

else if (*endptr == '\0') { /* the entire string was converted */ }

else { /* the unconverted rest of the string starts at endptr */ }

I think the only required error values are for underflow and overflow.

Conversely, if the entire string has been consumed in the conversion, you have *endptr = '\0', which may be an additional thing you might want to check.

like image 171
Kerrek SB Avatar answered Dec 07 '25 18:12

Kerrek SB


It has been 10 years since the question was first posted, but the problem does not age. The answers given are either out of date (yet true for their time) or a bit confusing because I had to search more.

I have seen this in a book and met this post while searching for its meaning, and while checking the page for strtol, I ended up in this page on cplusplus.com of errno macro.

Your question has 2 parts to answer here:

First lets make a note of these 2 things about errno:

1- errno can be anything during the execution of a program for no function resets it (unless your own function does so)

errno is set to zero at program startup ... any function ... can modify its value ... no ... function sets its value back to zero

2- one has to reset it before calling a function that may use it.

should be reset ... to zero before the call ... since ... previous ... function may have altered its value

your program is pretty small, so no function seems to be there to change it. The sole visitors of errno are main program to set it to zero, and strtol in case of any error.

Yet, your program shows errno is 0, and this is confusing because one expects 23ef23 would not be converted to a number since it includes letters in it. However, this expectation is wrong, and actually, you get a number from this string thus there is really no error here, so no change is made to errno. and this makes the second part of the answer.

you will find this definition in strtol page

... takes as many characters as possible that are valid following a syntax that depends on the base parameter, and interprets them as a numerical value ... a pointer to the first character following is stored.

instead of a long explanation, this following print statement and its output will suffice to visualize that above definition:

printf("%d %d %s",data,errno,tmp);
23 0 ef23

if you set the base to 16, output would be 2354979 0 . And base 2 would give 0 0 23ef23, showing that strtol will not freak if it does not find a number. The only error it will give will be ERANGE for breaching limits:

If the value read is out of the range of representable values by a long int, the function returns LONG_MAX or LONG_MIN (defined in ), and errno is set to ERANGE.

like image 27
Yılmaz Durmaz Avatar answered Dec 07 '25 19:12

Yılmaz Durmaz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!