Advertisement
Mary_99

strtol zanim sie zjebie

May 27th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.05 KB | None | 0 0
  1. #include <assert.h>
  2. #include <ctype.h>
  3. #include <errno.h>  
  4. #include <limits.h>
  5.  
  6.  
  7. long strtol(char* nptr, char **endptr , int base)
  8. {
  9.     char *string;  //points at the character being currently converted
  10.     long returnedNumber = 0;
  11.     int numberOutsideTheLimit = 0;
  12.     int sign;
  13.     int addedDigit;
  14.    
  15.    
  16.     assert(nptr); // quits if (nptr = NULL)
  17.     string = nptr;
  18.    
  19.     while(isspace(*string))
  20.     {
  21.         string++;
  22.     }
  23.  
  24.     if(*string =='-')
  25.     {
  26.         sign = 1;
  27.         string++;
  28.     }
  29.     else
  30.     {
  31.         if(*string =='+')
  32.         {
  33.             sign = 0;
  34.             string++;
  35.         }
  36.         else
  37.         {
  38.             sign = 0;
  39.         }
  40.     }
  41.    
  42.     if((base == 8) && (*string =='0'))
  43.     {
  44.         string++;
  45.     }
  46.    
  47.     if((base == 16) && (*string == '0'))
  48.     {
  49.         string++;
  50.        
  51.         if((*string =='x')||(*string =='X'))
  52.         {
  53.             string++;
  54.         }
  55.         else
  56.         {
  57.             string--;
  58.         }
  59.     }
  60.     if((*string =='0') && (base == 0))
  61.     {
  62.         base = 8;
  63.         string++;
  64.        
  65.         if((*string =='x')||(*string =='X'))
  66.         {
  67.             base = 16;
  68.             string++;
  69.         }  
  70.    
  71.     }
  72.     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
  73.     {
  74.         base = 10;
  75.     }
  76.    
  77.     if(base < 2 || base > 36)
  78.     {
  79.         errno = EINVAL;
  80.         return 0;
  81.     }
  82.    
  83.     if((base == 8) && ((*string < '0')||(*string >'7')))
  84.     {
  85.         *endptr = string;
  86.         return 0;
  87.     }  
  88.    
  89.     if((base == 16) && ((*string < '0') || ((*string > '9')&&(*string < 'A')) || ((*string > 'F') && (*string < 'a')) || (*string >'f')))
  90.     {
  91.         string--;
  92.         *endptr = string;
  93.         return 0;
  94.     }
  95.    
  96.     while(*string!='\0') /* This loop terminates when string points to the end of the file*/
  97.     {  
  98.         if (isdigit(*string))/* if string does not point to a digit isdigit returns 0, otherwise it returns this digit*/
  99.         {
  100.             addedDigit = *string - '0'; /*converting ASCII code to corresponding digit*/
  101.         }
  102.         else
  103.         {
  104.             if(isalpha(*string)) /* isalpha returns 0 if string does not point to a letter, otherwise it returns that letter */
  105.             {
  106.                 if(islower(*string)) /* checks if the string points to the lower case letter */
  107.                 {
  108.                     addedDigit = (*string - 'a') + 10; /* converts lower case letters in ASCII code to corresponding digits in numerical systems */
  109.                 }
  110.                 else
  111.                     addedDigit = (*string - 'A') + 10; /* converts upper case letters in ASCII code to corresponding digits in numerical systems */
  112.             }
  113.             else /* loop is terminated if string does not point to digits or letters */
  114.             {
  115.                 break;
  116.             }
  117.         }
  118.         switch(sign)
  119.         {
  120.         case 0:
  121.         {
  122.             if (numberOutsideTheLimit < 0 || returnedNumber > ((LONG_MAX-addedDigit)/base) /*|| (number == limit && (int) digit > limit_mod)*/)
  123.             {/* 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 */
  124.                 numberOutsideTheLimit =-1;
  125.                 string++;
  126.             }  
  127.             else /* if the number is inside the limits then numberOutsideTheLimit=1 and current digit is attached to the number */
  128.             {
  129.                 numberOutsideTheLimit = 1;
  130.                 returnedNumber = (returnedNumber*base)+addedDigit;
  131.                 string++;
  132.             }
  133.             break;
  134.    
  135.         }
  136.         case 1:
  137.         {
  138.             if (numberOutsideTheLimit < 0 || returnedNumber < ((LONG_MIN+addedDigit)/base))
  139.             {/* 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 */
  140.                 numberOutsideTheLimit =-1;
  141.                 string++;
  142.             }  
  143.             else /* if the number is inside the limits then numberOutsideTheLimit=1 and current digit is attached to the number */
  144.             {
  145.                 numberOutsideTheLimit = 1;
  146.                 returnedNumber = (returnedNumber*base)-addedDigit;
  147.                 string++;
  148.             }
  149.        
  150.             break;
  151.         }
  152.         }
  153.     }
  154.     if (numberOutsideTheLimit<0)/* if numberOutsideTheLimit=-1 then the number is outside limits so function will return LONG_MIN or LONG_MAX depending on sign */
  155.             {
  156.                 returnedNumber = sign ? LONG_MIN : LONG_MAX;
  157.                 errno = ERANGE;
  158.             }
  159.    
  160.     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) */
  161.         *endptr = numberOutsideTheLimit ? string : (char *) nptr;
  162.  
  163. return returnedNumber;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement