2
\$\begingroup\$

I have created a program that forms a basic calculator in C which includes the basic operations like addition, subtraction, multiplication and division. But in this case I decided to use a Do-While loop. It is working.

I would appreciate to be pointed out some mistakes and opinions to make the code more presentable.

I have only one question which is:

instead of using a single character like:

while( choice == 'y' || choice == 'Y' );

why can't I use a string? ie.

printf("would you like to try again? \"yes or no\"\n");
scanf(" %s", &choice);
}
while ( choice == 'yes' || choice == 'YES' );

My code is as given as below...

 #include <stdio.h>
 #include <stdlib.h>


 int main()
 {
     float a, b, c;
     int n;
     char choice = 'y' ;


     do
     {
         printf("Please enter any number:\n");
             if (scanf("%f", &a)!=1){
                 fprintf(stderr, "error: first input must be a number\n");
                     return EXIT_FAILURE;}


         printf("Please choose any of the operator:\n");
         printf(" 1.addition\n 2.subtraction\n 3.multiplication\n 4.division\n");
             scanf(" %d", &n);


         printf("Please enter any number:\n");
             if (scanf("%f", &b)!=1){
                 fprintf(stderr, "error: second input must be a number\n");
                     return EXIT_FAILURE;}


         switch(n)
         {
             case 1 :
                 c = a + b;
                     printf("The answer is:%f\n", c);
             break ;

             case 2 :
                 c = a - b;
                     printf("The answer is:%f\n", c);
             break;

             case 3 :
                 c = a * b;
                     printf("The answer is:%f\n", c);
             break;

             case 4 :
                 c = a / b;
                     printf("The answer is:%f\n", c);
             break;

             default :
                     printf("You have not chosen the given operators\n");
             }

                     printf("would you like to try again? (y/n)\n");
                         scanf(" %c", &choice);
     }

     while( choice == 'y' || choice == 'Y');
         getch();


     return 0;
 }
\$\endgroup\$
3
  • 3
    \$\begingroup\$ 'yes' isn't a string - it's a (multi-byte) character literal, which isn't valid C on most platforms. To compare strings in C, you need strcmp() (from <string.h>) rather than ==. \$\endgroup\$ – Toby Speight Feb 28 '19 at 15:48
  • 2
    \$\begingroup\$ The most serious issue here is the lack of indention. The code is, bluntly put, a mess. Which means I can't even be bothered reading it, let alone review it. So please study indention before you do anything else, then edit your post accordingly. Indent by 2 or 4 spaces and do so consistently. \$\endgroup\$ – Lundin Mar 1 '19 at 9:35
  • \$\begingroup\$ I have tried to indent it to my best of knowledge. If there is any other mistake that I haven't rectified, please direct me so. Thanks \$\endgroup\$ – O.Mukhtar Mar 1 '19 at 18:25
0
\$\begingroup\$

Indentation

Frankly, your indentation is all over the place!

The basic idea of indentation is that you indent based on scope. A scope begins with { and ends with } (you can omit the { } sometimes but you shouldn't). I'll indent a few snippets of your code and you can do the rest. You seem to put { on the next line more often than you put { on the same line so that's the convention I've used. Using this convention, the { should be indented to the same depth as the matching }.

printf("Please enter any number:\n");
if (scanf("%f", &a) != 1) 
{
    fprintf(stderr, "error: first input must be a number\n");
    return EXIT_FAILURE;
}

// ...

switch(n)
{
    case 1:
        c = a + b;
        printf("The answer is:%f\n", c);
        break;
}
printf("would you like to try again? (y/n)\n");
scanf(" %c", &choice);

Indentation is really the only major problem with this code.

Extensibility

You could use doubles instead of floats to gain a little bit of extra precision. If you want to make this program really easy to extend (after you've learnt about a bunch of new stuff) then you could store the operations in an array. Then the user will type add you'll look up a function pointer in an array. Something like this:

typedef struct {
    const char *name;
    double (*func)(double, double);
} Operation;

const Operation ops[] = {
    {"add", add},
    {"sub", sub}
    // ...
};

I'll let you figure out the details. Some things you'll need to look up are arrays, structs, function pointers and string comparison (strcmp).

Unary operations

You could complicate things further by allowing unary operations (e.g. sin, sqrt). You'll need separate arrays for unary and binary operations.

typedef struct {
    const char *name;
    double (*func)(double);
} UnaryOperation;

typedef struct {
    const char *name;
    double (*func)(double, double);
} BinaryOperation;

Parsing

If you're up for a real challenge you could allow the user to enter an expression like 14 + 2 * sin(0.8) and evaluate the expression. This sort of thing is quite tricky indeed! You'll need to learn about recursive descent parsing (there are other types of parsing but this is probably the easiest), memory management and pointers. The last time I did something like that, the resulting program was 700 lines so it's quite a step up from the code in your question.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.