Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <assert.h>
- #include <ctype.h>
- #include <errno.h>
- #include <limits.h>
- long strtol(char* nptr, char **endptr , int base)
- {
- char *string; //points at the character being currently converted
- long returnedNumber = 0;
- int numberOutsideTheLimit = 0;
- int sign;
- int addedDigit;
- assert(nptr); // quits if (nptr = NULL)
- string = nptr;
- while(isspace(*string))
- {
- string++;
- }
- if(*string =='-')
- {
- sign = 1;
- string++;
- }
- else
- {
- if(*string =='+')
- {
- sign = 0;
- string++;
- }
- else
- {
- sign = 0;
- }
- }
- if((base == 8) && (*string =='0'))
- {
- string++;
- }
- if((base == 16) && (*string == '0'))
- {
- string++;
- if((*string =='x')||(*string =='X'))
- {
- string++;
- }
- else
- {
- string--;
- }
- }
- if((*string =='0') && (base == 0))
- {
- base = 8;
- string++;
- if((*string =='x')||(*string =='X'))
- {
- base = 16;
- string++;
- }
- }
- else if(base == 0) //if the base is 0 and the beginning of string is not 0, 0x or 0X then the base is 10
- {
- base = 10;
- }
- if(base < 2 || base > 36)
- {
- errno = EINVAL;
- return 0;
- }
- if((base == 8) && ((*string < '0')||(*string >'7')))
- {
- *endptr = string;
- return 0;
- }
- if((base == 16) && ((*string < '0') || ((*string > '9')&&(*string < 'A')) || ((*string > 'F') && (*string < 'a')) || (*string >'f')))
- {
- string--;
- *endptr = string;
- return 0;
- }
- while(*string!='\0') /* This loop terminates when string points to the end of the file*/
- {
- if (isdigit(*string))/* if string does not point to a digit isdigit returns 0, otherwise it returns this digit*/
- {
- addedDigit = *string - '0'; /*converting ASCII code to corresponding digit*/
- }
- else
- {
- if(isalpha(*string)) /* isalpha returns 0 if string does not point to a letter, otherwise it returns that letter */
- {
- if(islower(*string)) /* checks if the string points to the lower case letter */
- {
- addedDigit = (*string - 'a') + 10; /* converts lower case letters in ASCII code to corresponding digits in numerical systems */
- }
- else
- addedDigit = (*string - 'A') + 10; /* converts upper case letters in ASCII code to corresponding digits in numerical systems */
- }
- else /* loop is terminated if string does not point to digits or letters */
- {
- break;
- }
- }
- switch(sign)
- {
- case 0:
- {
- if (numberOutsideTheLimit < 0 || returnedNumber > ((LONG_MAX-addedDigit)/base) /*|| (number == limit && (int) digit > limit_mod)*/)
- {/* checks if the number is inside the limits for long int, if not numberOutsideTheLimit=-1 and the string proceedes to the end of the file */
- numberOutsideTheLimit =-1;
- string++;
- }
- else /* if the number is inside the limits then numberOutsideTheLimit=1 and current digit is attached to the number */
- {
- numberOutsideTheLimit = 1;
- returnedNumber = (returnedNumber*base)+addedDigit;
- string++;
- }
- break;
- }
- case 1:
- {
- if (numberOutsideTheLimit < 0 || returnedNumber < ((LONG_MIN+addedDigit)/base))
- {/* checks if the number is inside the limits for long int, if not numberOutsideTheLimit=-1 and the string proceedes to the end of the file */
- numberOutsideTheLimit =-1;
- string++;
- }
- else /* if the number is inside the limits then numberOutsideTheLimit=1 and current digit is attached to the number */
- {
- numberOutsideTheLimit = 1;
- returnedNumber = (returnedNumber*base)-addedDigit;
- string++;
- }
- break;
- }
- }
- }
- if (numberOutsideTheLimit<0)/* if numberOutsideTheLimit=-1 then the number is outside limits so function will return LONG_MIN or LONG_MAX depending on sign */
- {
- returnedNumber = sign ? LONG_MIN : LONG_MAX;
- errno = ERANGE;
- }
- if (endptr != '\0') /* if endpointer is something other than NULL then for numberOutsideTheLimit=1 (number inside limits) it points to string (current character) and for numberOutsideTheLimit=-1 (number outside limits) it points to nptr (the whole string) */
- *endptr = numberOutsideTheLimit ? string : (char *) nptr;
- return returnedNumber;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement