Advertisement
Mary_99

strtol wzor

May 20th, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.27 KB | None | 0 0
  1. #include <assert.h> /* This library contains assert function*/
  2. #include <ctype.h> /* This library contains functions: isspace, isdigit, isalpha*/
  3. #include <errno.h>  /* variable errno is defined in this library */
  4. #include <limits.h> /*LONG_MIN, LONG_MAX */
  5.  
  6.  
  7. long strtol(char* nptr, char **endptr , int base)
  8. {/**
  9. \brief This is my strtol function. It converts strings to long integers
  10. *@param nptr This string points to a character string for function to convert
  11. *@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
  12. *@param base This is the base of the string; it's between 2 and 36
  13. */
  14. char *string;  /*points at the character being currently converted*/
  15. long number = 0; /*the number returned by this function*/
  16. int sign; /*sign of the number (1-negative, 0-positive)*/
  17. int digit; /* current digit added to the number */
  18. int isoutside = 0; /* variable useful in conditions of number being outside the limit */
  19.  
  20. assert(nptr); /* quits if string is empty (if the value of nptr is NULL)*/
  21. string = nptr; /* string points to the same place as nptr*/
  22.  
  23. while(isspace(*string)) /* checks if there are white signes (spaces, new lines etc.) at the beginning of the stringand ommits them */
  24. {
  25.     string++;
  26. }
  27. /* checks the sign of the number */
  28. if(*string=='-')
  29. {
  30.     sign = 1; /* negative number*/
  31.     string++;
  32. }
  33. else
  34. {
  35.     if(*string=='+')
  36.     {
  37.         sign = 0; /*positive number*/
  38.         string++;
  39.     }
  40.     else sign = 0; /*if there's no '+' or'-' sign we assume that the number is positive*/
  41. }
  42. /* Checks the bases and range of digits/letters for bases 8 and 16*/
  43. if((base==8)&&(*string=='0'))
  44.     string++;
  45. if((base==16)&&(*string=='0'))
  46. {
  47.     string++;
  48.     if((*string=='x')||(*string=='X'))
  49.         string++;
  50.     else string--;
  51. }
  52. if((*string=='0')&&(base==0))
  53. { /*if the base=0 and the first nonwhite character is 0 then the base is 8*/
  54.     base = 8;
  55.     string++;
  56.     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*/
  57.     {
  58.         base = 16;
  59.         string++;
  60.     }  
  61.    
  62. }
  63. 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*/
  64.     base = 10;
  65. if(base <2 || base >36)
  66. {
  67.     errno=EINVAL;/*if the base is outside the interval [2;36] then the string will not be converted and will return error-invalid argument*/
  68.     return 0;
  69. }
  70. if((base==8)&&((*string<'0')||(*string>'7')))
  71. /*checks if the values of the string are correct for the base 8: digits 0-7*/
  72. {
  73.     *endptr = string;
  74.     return 0;
  75. }                                            
  76. if((base==16)&&((*string<'0')||((*string>'9')&&(*string<'A'))||((*string>'F')&&(*string<'a'))||(*string>'f')))
  77. /*checks if the values of the string are correct for the base 16: digits 0-9, letters A-F, a-f*/
  78. {
  79.     string--;
  80.     *endptr = string;
  81.     return 0;
  82. }
  83.  
  84. while(*string!='\0') /* This loop terminates when string points to the end of the file*/
  85. {  
  86.     if (isdigit(*string))/* if string does not point to a digit isdigit returns 0, otherwise it returns this digit*/
  87.     {
  88.         digit = *string - '0'; /*converting ASCII code to corresponding digit*/
  89.     }
  90.     else
  91.     {
  92.         if(isalpha(*string)) /* isalpha returns 0 if string does not point to a letter, otherwise it returns that letter */
  93.         {
  94.             if(islower(*string)) /* checks if the string points to the lower case letter */
  95.             {
  96.                 digit = (*string - 'a') + 10; /* converts lower case letters in ASCII code to corresponding digits in numerical systems */
  97.             }
  98.             else
  99.                 digit = (*string - 'A') + 10; /* converts upper case letters in ASCII code to corresponding digits in numerical systems */
  100.         }
  101.         else /* loop is terminated if string does not point to digits or letters */
  102.         {
  103.             break;
  104.         }
  105.     }
  106.     switch(sign)
  107.     {
  108.     case 0:
  109.     {
  110.         if (isoutside < 0 || number > ((LONG_MAX-digit)/base) /*|| (number == limit && (int) digit > limit_mod)*/)
  111.         {/* 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 */
  112.             isoutside =-1;
  113.             string++;
  114.         }  
  115.         else /* if the number is inside the limits then isoutside=1 and current digit is attached to the number */
  116.         {
  117.             isoutside = 1;
  118.             number = (number*base)+digit;
  119.             string++;
  120.         }
  121.         break;
  122.    
  123.     }
  124.     case 1:
  125.     {
  126.         if (isoutside < 0 || number < ((LONG_MIN+digit)/base))
  127.         {/* 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 */
  128.             isoutside =-1;
  129.             string++;
  130.         }  
  131.         else /* if the number is inside the limits then isoutside=1 and current digit is attached to the number */
  132.         {
  133.             isoutside = 1;
  134.             number = (number*base)-digit;
  135.             string++;
  136.         }
  137.        
  138.         break;
  139.     }
  140.     }
  141. }
  142. if (isoutside<0)/* if isoutside=-1 then the number is outside limits so function will return LONG_MIN or LONG_MAX depending on sign */
  143.         {
  144.             number = sign ? LONG_MIN : LONG_MAX;
  145.             errno = ERANGE; /* error-value outside range */
  146.         }
  147.  
  148. 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) */
  149.     *endptr = isoutside ? string : (char *) nptr;
  150.  
  151. return number; /* function returns the converted number */
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement