Thread: Switch-case working

  1. #1
    Registered User
    Join Date
    Aug 2017
    Posts
    21

    Switch-case working

    Hello gentle folks,
    I almost tried to look for the answer in my books and in some other treads here but there's nothing about my little mind trick...
    I need to create a simple calculator with switch construct.
    No problems for that

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main()
    {
    	int op;
    	int a, b, c;
        int err;
        
        printf("Simple calculator\n");
        
        printf("Insert 1 to sum\n");
        printf("Insert 2 to subtracte\n");
        printf("Insert 3 to moltiplicate\n");
        printf("Insert 4 to divide\n");
        
        printf("Your choice: \n");
        scanf("%d", &op);
        printf("First operand : \n");
        scanf("%d", &a);
        printf("Second operand: \n");
        scanf("%d", &b);
        
        /*Initializing error condition*/
        err = 0;
        /*Execute requested operation*/
        switch( op )
        {
    		case 1:
    		  c = a + b;
    		  break;
    		case 2:
    		  c = a - b;
    		  break;
    		case 3:
    		  c = a * b;
    		  break;
    		case 4:
    		  if( b == 0 )
    		  {
    			  printf("Can't  be divided for 0!\n");
    			  err = 1;
    		  }
    		  else
    		  {
    			  c = a / b;
    		  }
    		  break;
    		default:
    		    printf("Error\n");
    		    err = 1;
        }
    		
        if( err == 0 )
           printf("Result value: %d\n", c);
     exit(0);
    }
    This works perfectly,
    My question is: when i go to terminal and execute this, if I type 1,2,3,4 i get no error and i select sum,multiplication ecc... ; but if I type 0, 5, 6, 7, -7634762 or 589627962166 it's the same because the program follows the "flow" and asks me operands,saying me "insert first and second operand.Can I stop that to the point before it asks me "insert operands"?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Sure, you just need your switch before you ask for the operand values.
    Code:
        switch( op )
        {
            case 1:
              getOperands(&a,&b);
              c = a + b;
              break;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Aug 2017
    Posts
    21
    Thank you,
    Should I use "getOperands(&a,&b);" even in default case?
    I think...Is this a special function like "fgetpos" or something else?
    And by the way..why do I find, with recurrence, additional functions not explained anywhere?
    I may understand the rare usage or similar causes, but it's important anyways...like the usage of macros, I think...
    Last edited by Alcatraz; 10-01-2018 at 08:39 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Should I use "getOperands(&a,&b);" even in default case?
    That would seem unnecessary to me.

    > I think...Is this a special function like "fgetpos" or something else?
    No, it's something you would have to write for yourself.
    It's just your two printf/scanf calls wrapped in a nice little function you can re-use.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Aug 2017
    Posts
    21
    I tried as you said and even in different ways...I can't compile the code because compiler says it is undefined,and that's how it is...
    I think books should explain this mechanisms...They just put students at the bottom of the barrel leaving holes in some arguments
    Right now i can't define this, later I won't be able to define something else or some new sort of thing will appear...

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You need to study more.
    Code:
    void getOperands(int *a, int *b) {
        printf("First operand : \n");
        scanf("%d", a);
        printf("Second operand: \n");
        scanf("%d", b);
    }
    Post your actual code and actual error messages when you're stuck.

    "I tried .... and got an error of some sort" doesn't allow us to help you.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Aug 2017
    Posts
    21
    I'm sorry for not being precise before.
    On the way I didn't even know that i could use a void function with pointers inside the main() one.
    I mean,there are so many cases that books should illustrate more...
    I changed code to this
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main()
    {
    	int op;
    	float a, b, c;
        int err;
        
        printf("Semplice Calcolatrice\n");
        
        printf("Inserisci 1 per la somma\n");
        printf("Inserisci 2 per la sottrazione\n");
        printf("Inserisci 3 per la moltiplicazione\n");
        printf("Inserisci 4 per la divisione\n");
        
        printf("La tua scelta: \n");
        scanf("%d", &op);
        
        void getOperands(float *a, float *b)
        {
         printf("Immetti il primo operando: \n");
         scanf("%f", a);
         printf("Inserisci il secondo operando: \n");
         scanf("%f", b);
        }
        /*La condizione di errore viene inizializzata*/
        err = 0;
        /*Esegui l'operazione richiesta*/
        switch( op )
        {
    		case 1:
    		  getOperands( &a, &b);
    		  c = a + b;
    		  break;
    		case 2:
    		  getOperands( &a, &b);
    		  c = a - b;
    		  break;
    		case 3:
    		  getOperands( &a, &b);
    		  c = a * b;
    		  break;
    		case 4:
    		  getOperands( &a, &b);
    		  if( b == 0 )
    		  {
    			  printf("Impossibile dividere per zero!\n");
    			  err = 1;
    		  }
    		  else
    		  {
    			  getOperands(&a,&b);
    			  c = a / b;
    		  }
    		  break;
    		default:
    		    printf("Operazione errata\n");
    		    err = 1;
        }
    		
        if( err == 0 )
           printf("Il risultato vale: %f\n", c);
     exit(0);
    }
    Before changing to floats i tried with integers and program works perfectly,so thank you.
    But I guessed what would happen if i tried with floats.
    I tried but i think I'm mistaking something I don't know about.
    Why the program ends?
    Switch-case working-schermata-2018-10-02-18-04-36-jpg

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
        void getOperands(float *a, float *b)
        {
         printf("Immetti il primo operando: \n");
         scanf("%f", a);
         printf("Inserisci il secondo operando: \n");
         scanf("%f", b);
        }
    C doesn't support nested functions.
    Move this so it's above main()

    > On the way I didn't even know that i could use a void function with pointers inside the main() one.
    I think you need better reference material then.

    > I mean,there are so many cases that books should illustrate more...
    If books explained every single permutation possible, they would be 1000's of pages long and nobody would read them.
    You have to understand general concepts, then figure out how to apply that knowledge to specific problems.


    Also, delete line 54 - you already got (and validated) the a and b values.


    > I tried but i think I'm mistaking something I don't know about.
    Well looking at your screen shot, you typed in "7,4".
    Your scanf calls as they stand need the values to be separated by white space (spaces, tabs, newlines).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Aug 2017
    Posts
    21
    >I typed 7,4
    I tried with 7.4 (i tried to use dot) and it works.

    >Move this so it's above main()
    I'd like to understand the reason...Are you saying this is better for compiler?

    > I think you need better reference material then. / If books explained every single permutation possible, they would be 1000's of pages long and nobody would read them.

    I understand general concepts, but according to what you say Medicine or Law or other arguments should be all general? So why do I buy books if I can't read about specific parts?
    My reference material is C book in my motherlanguage made by a university teacher...I even have K&R and when everyone says it's a sacred book...well I don't think so when i can't find (important) specific argument.
    I've never read getOperands anywhere...
    Time ago I had a problem with Array lenght..I looked so hard everywhere for that mystical "ARRLEN" and books didn't explain what that was...
    I understand what you say...but I think i miss explanations to understand the step between general concepts and specific problems. At least in C language. I think I'll be confident when I understand the "range" of C language, I mean what I can do more and understand from a general concept moving to specific problems

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I'd like to understand the reason...Are you saying this is better for compiler?
    No, I'm saying that's because what the C standard says you must do.
    Some languages allow nested function declarations, C does not.
    GCC (for reasons known only to GCC developers) allows nested functions, but you're going to be SoL when using another compiler.

    gcc -Wall -std=c99 prog.c
    Is a good start to making GCC warn about all sorts of potential issues, and not dragging in all the "enhancements" which would mean your code would not compile on another compiler.

    > I've never read getOperands anywhere...
    That's because I just made the name up on the spot when I replied to your post!
    Specifically, I was trying to give you a meaningful name to describe what the function does.

    Would you be more or less happy if I'd written
    Code:
    void foo(float *a, float *b)
    {
     printf("Immetti il primo operando: \n");
     scanf("%f", a);
     printf("Inserisci il secondo operando: \n");
     scanf("%f", b);
    }

    > >I typed 7,4
    > I tried with 7.4 (i tried to use dot) and it works.
    That's all down to the locale.
    The standard "C" locale is "English" in nature. You can alter this in your programs, but it involves doing several more things which are not the natural first programming steps.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Aug 2017
    Posts
    21
    >Some languages allow nested function declarations, C does not.
    Ok now I understand..As normally we have to declare functions before main(),but I went in confusion just because when you first suggested me,I thought that I had to declare that function before.
    So overall I just created a function for my purpose and I'm gonna recall this void-pointers function on every switch case, right?

    Last question...I executed my "updated" program
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    void getOperands(float *a, float *b)
    {
      printf("Immetti il primo operando: \n");
      scanf("%f", a);
      printf("Inserisci il secondo operando: \n");
      scanf("%f", b);
    }
    int main()
    {
    	int op;
    	float a, b, c;
        int err;
        
        printf("Semplice Calcolatrice\n");
        
        printf("Inserisci 1 per la somma\n");
        printf("Inserisci 2 per la sottrazione\n");
        printf("Inserisci 3 per la moltiplicazione\n");
        printf("Inserisci 4 per la divisione\n");
        
        printf("La tua scelta: \n");
        scanf("%d", &op);
        
        /*La condizione di errore viene inizializzata*/
        err = 0;
        /*Esegui l'operazione richiesta*/
        switch( op )
        {
    		case 1:
    		  getOperands( &a, &b);
    		  c = a + b;
    		  break;
    		case 2:
    		  getOperands( &a, &b);
    		  c = a - b;
    		  break;
    		case 3:
    		  getOperands( &a, &b);
    		  c = a * b;
    		  break;
    		case 4:
    		  getOperands( &a, &b);
    		  if( b == 0 )
    		  {
    			  printf("Impossibile dividere per zero!\n");
    			  err = 1;
    		  }
    		  else
    		  {
    			  c = a / b;
    		  }
    		  break;
    		default:
    		    printf("Operazione errata\n");
    		    err = 1;
        }
    		
        if( err == 0 )
           printf("Il risultato vale: %f\n", c);
     exit(0);
    }
    How can be possible that "Insert 1 to sum" comes before of "Insert first operand"? Switch-case working-schermata-2018-10-03-17-33-32-png

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > How can be possible that "Insert 1 to sum" comes before of "Insert first operand"?
    Huh?

    Because that's the order in which the printf() statements are written in your code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Aug 2017
    Posts
    21
    I guess that's because main() has the priority, right?

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You have to understand that the order of functions in your source file makes absolutely NO difference to what happens when you run the code.

    The program always starts at main(), and from that point you can follow how the execution of the program would proceed by reading each line of main(). That's why your first six printf's happen first, in the order you wrote them in. At some point, getOperands() is called, and when that returns, main carries on from where it left off.


    Also, the order of functions in your source makes almost no practical difference to the compiler. In fact, putting main last is a somewhat lazy approach while you have the benefit of being able to write a small program in a single source file. Larger projects have 10's, 100's or 1000's of source files, but they all begin somewhere with a single main() function.

    For example, these two programs would compile the same.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    void getOperands(float *a, float *b)
    {
      printf("Immetti il primo operando: \n");
      scanf("%f", a);
      printf("Inserisci il secondo operando: \n");
      scanf("%f", b);
    }
    int main()
    {
        int op;
        float a, b, c;
        int err;
         
        printf("Semplice Calcolatrice\n");
         
        printf("Inserisci 1 per la somma\n");
        printf("Inserisci 2 per la sottrazione\n");
        printf("Inserisci 3 per la moltiplicazione\n");
        printf("Inserisci 4 per la divisione\n");
         
        printf("La tua scelta: \n");
        scanf("%d", &op);
         
        /*La condizione di errore viene inizializzata*/
        err = 0;
        /*Esegui l'operazione richiesta*/
        switch( op )
        {
            case 1:
              getOperands( &a, &b);
              c = a + b;
              break;
            case 2:
              getOperands( &a, &b);
              c = a - b;
              break;
            case 3:
              getOperands( &a, &b);
              c = a * b;
              break;
            case 4:
              getOperands( &a, &b);
              if( b == 0 )
              {
                  printf("Impossibile dividere per zero!\n");
                  err = 1;
              }
              else
              {
                  c = a / b;
              }
              break;
            default:
                printf("Operazione errata\n");
                err = 1;
        }
             
        if( err == 0 )
           printf("Il risultato vale: %f\n", c);
     exit(0);
    }
    vs.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    // This is a function prototype.
    // It's purpose is to inform the compiler that the function
    // getOperands() will exist at some point in the future,
    // either later in this file, or perhaps some other file.
    // Regardless of where it is, the compiler has enough
    // information to allow you to make calls to this function
    // within main(), or indeed any other function following in
    // this source file.
    void getOperands(float *a, float *b);
    
    int main()
    {
        int op;
        float a, b, c;
        int err;
         
        printf("Semplice Calcolatrice\n");
         
        printf("Inserisci 1 per la somma\n");
        printf("Inserisci 2 per la sottrazione\n");
        printf("Inserisci 3 per la moltiplicazione\n");
        printf("Inserisci 4 per la divisione\n");
         
        printf("La tua scelta: \n");
        scanf("%d", &op);
         
        /*La condizione di errore viene inizializzata*/
        err = 0;
        /*Esegui l'operazione richiesta*/
        switch( op )
        {
            case 1:
              getOperands( &a, &b);
              c = a + b;
              break;
            case 2:
              getOperands( &a, &b);
              c = a - b;
              break;
            case 3:
              getOperands( &a, &b);
              c = a * b;
              break;
            case 4:
              getOperands( &a, &b);
              if( b == 0 )
              {
                  printf("Impossibile dividere per zero!\n");
                  err = 1;
              }
              else
              {
                  c = a / b;
              }
              break;
            default:
                printf("Operazione errata\n");
                err = 1;
        }
             
        if( err == 0 )
           printf("Il risultato vale: %f\n", c);
     exit(0);
    }
    
    void getOperands(float *a, float *b)
    {
      printf("Immetti il primo operando: \n");
      scanf("%f", a);
      printf("Inserisci il secondo operando: \n");
      scanf("%f", b);
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 0
    Last Post: 03-09-2016, 03:58 PM
  2. Simple switch case with date not working
    By Leston Yearwood in forum C Programming
    Replies: 6
    Last Post: 09-05-2015, 10:56 AM
  3. switch-case statement not working properly
    By Shinzu911 in forum C Programming
    Replies: 11
    Last Post: 04-25-2012, 10:41 AM
  4. C: Default case in switch not working
    By LunaLux in forum C Programming
    Replies: 5
    Last Post: 04-24-2011, 08:46 AM
  5. case switch not working
    By AmbliKai in forum C Programming
    Replies: 2
    Last Post: 10-09-2008, 06:42 AM

Tags for this Thread