Advertisement
Phr0zen_Penguin

myIntegralScanf.c

Nov 23rd, 2013
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.74 KB | None | 0 0
  1. /*============================================================================
  2.   ----------------------------------------------------------------------------
  3.   myIntegralScanf.c - A scanf alternative (for integers only).
  4.                  (c) Damion 'Phr0z3n.Dev' Tapper, 2013.
  5.                  Email: Phr0z3n.Dev@Gmail.com
  6.  
  7.   NOTE: Consider it secure.
  8.   ----------------------------------------------------------------------------
  9.   ============================================================================*/
  10. #define USE_SEC_API /* Comment this line if you do not have the secure libraries. */
  11.  
  12. #include <stdio.h>  /* For the printf function. */
  13. #include <conio.h>  /* For the getch function. */
  14. #include <ctype.h>  /* For the isdigit function. */
  15. #include <math.h>   /* For the pow function. */
  16.  
  17. /* Variable name definitions. */
  18. #define POSITION                pmss->position
  19. #define INCREMENT               pmss->increment
  20. #define BUFFER                  pmss->charArray
  21. #define ENTRY                   pmss->entry
  22. #define INPUT                   pmss->entry = getch()
  23. #define OFFSET                  BUFFER[0]
  24. #define ENTER_IS_NOT_PRESSED    ENTRY != 13
  25.  
  26. #define RESET_POSITION          POSITION = 1
  27.  
  28. /* Type definitions. */
  29. typedef struct  myScanfStruct   MSS;
  30. typedef struct  myScanfStruct*  PMSS; /* Hungarian notation.  Ummmm... */
  31.  
  32. struct myScanfStruct
  33. {
  34.     int entry;
  35.     int increment;
  36.     int position;
  37.     char    charArray[]; /* Unconventional but allowed. */
  38. };
  39.  
  40. /* Function prototypes definitions. */
  41. static void myScanf(struct myScanfStruct *); /* ...with limited scope (static).*/
  42.  
  43. int main(void)
  44. {
  45.     /* NOTE: Pointers are always perfect to reduce pushing and popping on the
  46.      * stack.
  47.      * The variable is also declared local for maximum security.
  48.      */
  49.     PMSS    pmss;
  50.  
  51.     /*
  52.      * No return value is needed because a pointer is used.
  53.      * Such is the nature of functions in the secure library.
  54.      * ...unless there is an (unlikely) error...
  55.      */
  56.     myScanf(pmss);
  57.  
  58.     /* TEST */
  59. #ifdef USE_SEC_API
  60.     printf_s("\n%d", ENTRY - 10); /* The secure printf function (good programming practice). */
  61.     /*
  62.      * Notice how you entered digits (characters) but a number was subtracted
  63.      * from the result.
  64.      */
  65. #else
  66.     /* If you are lacking the secure libraries. */
  67.     printf("\n%d", ENTRY - 10);
  68. #endif
  69.  
  70.     return 0;
  71. }
  72.  
  73. static void myScanf(struct myScanfStruct *pmss)
  74. {
  75.     RESET_POSITION; /* Each time the function is called. */
  76.  
  77.         /*
  78.          * A 32-bit integer (or long) allows only 10 digits so provisions
  79.          * must be made accordingly.  The code can be altered to accommodate
  80.          * entry for a 64-bit integer (long long) (19 digits).
  81.          */
  82.         for(INCREMENT = 0; INCREMENT <= 10; INCREMENT++)
  83.             BUFFER[INCREMENT] = '\0';
  84.  
  85.         /* Accept entry... */
  86.         do
  87.         {
  88.             INPUT;
  89.                 /* While an entry is being made... */
  90.                 if((isdigit(ENTRY) || (POSITION == 1 && ENTRY == '-')) && POSITION <= 10)
  91.                 {
  92.                     printf("%c", ENTRY);
  93.                     BUFFER[POSITION] = ENTRY;
  94.                     POSITION++;
  95.                 }
  96.  
  97.                 /* While backspace is pressed... */
  98.                 if(ENTRY == 8 && POSITION > 1)
  99.                 {
  100.                     BUFFER[POSITION] = '\0';
  101.                     printf("\b \b");
  102.                     POSITION--;
  103.                 }
  104.         }
  105.         while(ENTER_IS_NOT_PRESSED);
  106.  
  107.     /*
  108.      * A terminating character is assigned.  '\0' would be an unwise choice since
  109.      * any number ending with 0 (multiple of 10) entered could be misinterpreted.
  110.      * Besides 'ENTER' usually invokes the new line character.
  111.      */
  112.     BUFFER[POSITION] = '\n';
  113.  
  114.         /* If a negative number is entered... */
  115.         if(BUFFER[1] == '-')
  116.         {
  117.             OFFSET = '-';
  118.             BUFFER[1] = '0';
  119.         }
  120.  
  121.         /* Entry conversion: from characters to digits (integers). */
  122.         for(POSITION = 0; BUFFER[POSITION] != '\n'; POSITION++)
  123.         {
  124.             switch(BUFFER[POSITION])
  125.             {
  126.             case '0':
  127.                 BUFFER[POSITION] = 0;
  128.                 break;
  129.             case '1':
  130.                 BUFFER[POSITION] = 1;
  131.                 break;
  132.             case '2':
  133.                 BUFFER[POSITION] = 2;
  134.                 break;
  135.             case '3':
  136.                 BUFFER[POSITION] = 3;
  137.                 break;
  138.             case '4':
  139.                 BUFFER[POSITION] = 4;
  140.                 break;
  141.             case '5':
  142.                 BUFFER[POSITION] = 5;
  143.                 break;
  144.             case '6':
  145.                 BUFFER[POSITION] = 6;
  146.                 break;
  147.             case '7':
  148.                 BUFFER[POSITION] = 7;
  149.                 break;
  150.             case '8':
  151.                 BUFFER[POSITION] = 8;
  152.                 break;
  153.             case '9':
  154.                 BUFFER[POSITION] = 9;
  155.                 break;
  156.             }
  157.         }      
  158.  
  159.         /*
  160.          * If for some 'curious' reason zeroes are entered before the number...
  161.          * Such a number is still valid (by law) so...
  162.          */
  163.         for(POSITION = 1; BUFFER[POSITION] == 0; POSITION++)
  164.             ;
  165.  
  166.         /* ...remove leading zeroes. */
  167.         for(INCREMENT = 1; BUFFER[POSITION] != '\n'; INCREMENT++, POSITION++)
  168.             BUFFER[INCREMENT] = BUFFER[POSITION];
  169.  
  170.         /* Convert the entry to one integer. */
  171.         for(ENTRY = 0, POSITION = 1, INCREMENT -= 2; INCREMENT >= 0; POSITION++, INCREMENT--)
  172.             ENTRY += BUFFER[POSITION] * pow(10, INCREMENT);
  173.  
  174.         /* ...if the entry is negative. */
  175.         if(OFFSET == '-')
  176.             ENTRY = -ENTRY;
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement