SHARE
TWEET

myIntegralScanf.c

Phr0zen_Penguin Nov 23rd, 2013 47 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
Top