Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <assert.h> /* This library contains assert function*/
- #include <ctype.h> /* This library contains functions: isspace, isdigit, isalpha*/
- #include <errno.h> /* variable errno is defined in this library */
- #include <limits.h> /*LONG_MIN, LONG_MAX */
- long strtol(char* nptr, char **endptr , int base)
- {/**
- \brief This is my strtol function. It converts strings to long integers
- *@param nptr This string points to a character string for function to convert
- *@param endptr This is resulting parameter that normally indicates NULL, but if strtol is unable to convert something endptr points to the first unconverted character
- *@param base This is the base of the string; it's between 2 and 36
- */
- char *string; /*points at the character being currently converted*/
- long number = 0; /*the number returned by this function*/
- int sign; /*sign of the number (1-negative, 0-positive)*/
- int digit; /* current digit added to the number */
- int isoutside = 0; /* variable useful in conditions of number being outside the limit */
- assert(nptr); /* quits if string is empty (if the value of nptr is NULL)*/
- string = nptr; /* string points to the same place as nptr*/
- while(isspace(*string)) /* checks if there are white signes (spaces, new lines etc.) at the beginning of the stringand ommits them */
- {
- string++;
- }
- /* checks the sign of the number */
- if(*string=='-')
- {
- sign = 1; /* negative number*/
- string++;
- }
- else
- {
- if(*string=='+')
- {
- sign = 0; /*positive number*/
- string++;
- }
- else sign = 0; /*if there's no '+' or'-' sign we assume that the number is positive*/
- }
- /* Checks the bases and range of digits/letters for bases 8 and 16*/
- 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))
- { /*if the base=0 and the first nonwhite character is 0 then the base is 8*/
- base = 8;
- string++;
- if((*string=='x')||(*string=='X'))/*if the base is 0 and the first two nonwhite characters are 0x or 0X then the base is 16*/
- {
- 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;/*if the base is outside the interval [2;36] then the string will not be converted and will return error-invalid argument*/
- return 0;
- }
- if((base==8)&&((*string<'0')||(*string>'7')))
- /*checks if the values of the string are correct for the base 8: digits 0-7*/
- {
- *endptr = string;
- return 0;
- }
- if((base==16)&&((*string<'0')||((*string>'9')&&(*string<'A'))||((*string>'F')&&(*string<'a'))||(*string>'f')))
- /*checks if the values of the string are correct for the base 16: digits 0-9, letters A-F, a-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*/
- {
- digit = *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 */
- {
- digit = (*string - 'a') + 10; /* converts lower case letters in ASCII code to corresponding digits in numerical systems */
- }
- else
- digit = (*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 (isoutside < 0 || number > ((LONG_MAX-digit)/base) /*|| (number == limit && (int) digit > limit_mod)*/)
- {/* checks if the number is inside the limits for long int, if not isoutside=-1 and the string proceedes to the end of the file */
- isoutside =-1;
- string++;
- }
- else /* if the number is inside the limits then isoutside=1 and current digit is attached to the number */
- {
- isoutside = 1;
- number = (number*base)+digit;
- string++;
- }
- break;
- }
- case 1:
- {
- if (isoutside < 0 || number < ((LONG_MIN+digit)/base))
- {/* checks if the number is inside the limits for long int, if not isoutside=-1 and the string proceedes to the end of the file */
- isoutside =-1;
- string++;
- }
- else /* if the number is inside the limits then isoutside=1 and current digit is attached to the number */
- {
- isoutside = 1;
- number = (number*base)-digit;
- string++;
- }
- break;
- }
- }
- }
- if (isoutside<0)/* if isoutside=-1 then the number is outside limits so function will return LONG_MIN or LONG_MAX depending on sign */
- {
- number = sign ? LONG_MIN : LONG_MAX;
- errno = ERANGE; /* error-value outside range */
- }
- if (endptr != '\0') /* if endpointer is something other than NULL then for isoutside=1 (number inside limits) it points to string (current character) and for isoutside=-1 (number outside limits) it points to nptr (the whole string) */
- *endptr = isoutside ? string : (char *) nptr;
- return number; /* function returns the converted number */
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement