fork download
  1. /*
  2.  * Starting with C: Primitive 2 operands calculator
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <ctype.h> // for tolower()
  7. #include <math.h> // for pow(), sqrt(), ...
  8. #include <stdlib.h> // for exit()
  9. #include <errno.h> // for errno
  10.  
  11. #define MAXSLEN_LINEBUF 255+1 // for reading menu * nums as a strings
  12.  
  13. typedef enum { FALSE=0, TRUE } bool; // our custom boolean type
  14.  
  15. // -------------------------------------------------------------------------------
  16. // Read s from stdin until either 'ENTER is pressed or len-1 chars have been entered
  17. // Remove ENTER (if any), null terminate s and return it
  18. //
  19. char *s_get(char *s, size_t len)
  20. {
  21. register char *cp;
  22.  
  23. for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
  24. ; // for-loop with empty body */
  25. *cp = '\0'; // null-terminate last character
  26.  
  27. return s;
  28. }
  29.  
  30. // -------------------------------------------------------------------------------
  31. // Read num as a string from stdin and convert it to double. Demand a successfull
  32. // convertion (otherwise keep asking). The conversion is done via the standard
  33. // function: strtod()... read the C manual for more info.
  34. //
  35. void num_askuser( char *prompt, double *num, int maxslen_num )
  36. {
  37. char inbuf[ maxslen_num ], *pend=NULL;
  38. bool stop;
  39.  
  40. do
  41. {
  42. errno = 0; // reset errno (defined in <errno.h>
  43. stop = TRUE; // reset boolen flag
  44.  
  45. printf( prompt ); // display a prompt asking for input
  46. fflush(stdin); // clear the input buffer (stdin)
  47. s_get( inbuf, maxslen_num ); // read user input as string in inbuf
  48.  
  49. *num = strtod( inbuf, &pend ); // convert it to double
  50. if ( *pend ) // *pend != '\0', possibly invalid num
  51. {
  52. if ( *num == 0.0 ) { // num was indeed invalid, not converted
  53. puts("\t*** error: invalid number");
  54. stop = FALSE;
  55. continue;
  56. }
  57. else { // converted ok, invalid chars ignored
  58. printf("\t*** info: \"%s\" ignored\n", pend);
  59. stop = TRUE;
  60. continue;
  61. }
  62. }
  63.  
  64. if ( errno == ERANGE ) // too big (or too small) num
  65. {
  66. puts("\t*** error: number out of range");
  67. stop = FALSE;
  68. }
  69.  
  70. } while ( !stop || *inbuf =='\0' );
  71.  
  72. return;
  73. }
  74.  
  75. // -------------------------------------------------------------------------------
  76. int main (void)
  77. {
  78. double x, y; // operands
  79. int stop = FALSE; // boolean controlling the main loop
  80. #ifdef __GNUC__
  81. char inbuf[ MAXSLEN_LINEBUF ]; // menu choice
  82. #endif
  83. do { // display menu
  84. puts("\n\nAVAILABLE OPTIONS\n=================");
  85. printf ("1 or +\t add\n2 or -\t subtract\n3 or *\t multiply\n4 or /\t divide\n5 or %%\t percentage\n6 or ^\t power\n7\t square root\n8 or x\t exit\n\nYour choice: ");
  86.  
  87. fflush(stdin); // clear input buffer
  88. #ifdef __GNUC__
  89. switch ( tolower( *s_get(inbuf, MAXSLEN_LINEBUF) ) )// GET USER CHOICE
  90. #else
  91. switch ( tolower( getchar() ) ) // GET USER CHOICE
  92. #endif
  93. {
  94. case '1': // 1. ADDITTION
  95. case '+':
  96. puts("\nAddition\n--------");
  97. num_askuser("1st addendum: ", &x, MAXSLEN_LINEBUF);
  98. num_askuser("2nd addendum: ", &y, MAXSLEN_LINEBUF);
  99. printf ("--------\nRESULT: %g + %g = %g\n",
  100. x, y, x + y );
  101. break;
  102.  
  103. case '2': // 2. SUBTRACTION
  104. case '-':
  105. puts("\nSubtraction\n-----------");
  106. num_askuser("Reducer : ", &x, MAXSLEN_LINEBUF);
  107. num_askuser("Subtrahend: ", &y, MAXSLEN_LINEBUF);
  108. printf ("-----------\nRESULT: %g - %g = %g\n",
  109. x, y, x - y );
  110. break;
  111.  
  112. case '3': // 3. MULTIPLICATION
  113. case '*':
  114. puts("\nMultiplication\n--------------");
  115. num_askuser("1st number: ", &x, MAXSLEN_LINEBUF);
  116. num_askuser("2nd number: ", &y, MAXSLEN_LINEBUF);
  117. printf ("--------------\nRESULT: %g * %g = %g\n",
  118. x, y, x * y );
  119. break;
  120.  
  121. case '4': // 4. DIVISION
  122. case '/':
  123. { double intpart;
  124. puts("\nDivision\n--------");
  125. num_askuser("Divident: ", &x, MAXSLEN_LINEBUF);
  126. do { // demand non-zero value
  127. num_askuser("Divisor : ", &y, MAXSLEN_LINEBUF);
  128. if ( y == 0.0 )
  129. puts("*** error: divisor cannot be 0");
  130. } while (y == 0.0);
  131. printf ("--------\nRESULT: %g / %g = %g (quotient = %g, remainder = %g)\n",
  132. x, y, x/y, trunc(x/y), y * modf(x/y, &intpart) );
  133. }
  134. break;
  135.  
  136. case '5': // 5. PERCENTAGE
  137. case '%':
  138. puts("\nPercentage\n----------");
  139. num_askuser("Number: ", &x, MAXSLEN_LINEBUF);
  140. printf ("----------\nRESULT: %g%% = %g\n", x, x/100);
  141. break;
  142.  
  143. case '6': // 6. POWER
  144. case '^':
  145. puts("\nPower\n-----");
  146. num_askuser("Base : ", &x, MAXSLEN_LINEBUF);
  147. num_askuser("Exponent: ", &y, MAXSLEN_LINEBUF);
  148. printf ("-----\nRESULT: %g ^ %g = %g\n", x, y, pow(x, y));
  149. break;
  150.  
  151. case '7': // 7. SQUARE ROOT
  152. puts("\nSquare Root\n-----------");
  153. num_askuser("Number: ", &x, MAXSLEN_LINEBUF);
  154. printf ("-----------\nRESULT: sqrt(%g) = %g\n", x, sqrt(x) );
  155. break;
  156.  
  157. case '8': // 8. EXIT
  158. case 'x':
  159. stop = TRUE;
  160. break;
  161.  
  162. default: // ALL OTHER CHOICES
  163. puts("*** error: invalid choice, try again...");
  164. break;
  165. } // switch
  166.  
  167. } while ( !stop );
  168.  
  169. exit( 0 );
  170. }
  171.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty