strtol using errno

妖精的绣舞 提交于 2019-12-30 11:33:05

问题


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.


回答1:


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.




回答2:


You have to set errno to 0 before you call strtol. Otherwise you overwrite whatever value strtol set errno to.




回答3:


Your logic does not fit with the 'spec'. see this An invalid value does not necessarily set 'errno'.

(copy follows)
long int strtol ( const char * str, char ** endptr, int base );

Convert string to long integer Parses the C string str interpreting its content as an integral number of the specified base, which is returned as a long int value.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, 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. Finally, a pointer to the first character following the integer representation in str is stored in the object pointed by endptr.

If the value of base is zero, the syntax expected is similar to that of integer constants, which is formed by a succession of:

An optional plus or minus sign An optional prefix indicating octal or hexadecimal base ("0" or "0x" respectively)
A sequence of decimal digits (if no base prefix was specified) or either octal or
hexadecimal digits if a specific prefix is present

If the base value is between 2 and 36, the format expected for the integral number is a succession of the valid digits and/or letters needed to represent integers of the specified radix (starting from '0' and up to 'z'/'Z' for radix 36). The sequence may optionally be preceded by a plus or minus sign and, if base is 16, an optional "0x" or "0X" prefix.

If the first sequence of non-whitespace characters in str is not a valid integral number as defined above, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

Parameters
str C string containing the representation of an integral number. endptr Reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value. This parameter can also be a null pointer, in which case it is not used.

Return Value
On success, the function returns the converted integral number as a long int value. If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, LONG_MAX or LONG_MIN is returned, and the global variable errno is set to ERANGE.




回答4:


You have to check tmp is not the same as "blablabla" pointer.

If data == 0 and tmp == "blablabla", then the input data is in the incorrect format. errno needs not to be set by the implementation if the input data is not in the expected format.

On strtol, strtoll, strtoul, and strtoull functions C says:

(C99, 7.20.1.4p7) If the subject sequence is empty or does not have the expected form, no conversion is performed; the value of nptr is stored in the object pointed to by endptr, provided that endptr is not a null pointer.

(C99, 7.20.1.4p9) The strtol, strtoll, strtoul, and strtoull functions return the converted value, if any. If no conversion could be performed, zero is returned.



来源:https://stackoverflow.com/questions/9445171/strtol-using-errno

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!