Search code examples
cswitch-statement

Grading system by using switch statement


i've posted it before. but i want to make it way more concise. and now it is not working. i want to input marks of the students and likewise want to get the grade afterwhile. but it is not totally working . value that i ever input here are showing off just "F". that's so annoying. Would you please help me with my shortcomings in this code that will make it more accepting to others.

#include<stdio.h>
int main()

{
    int num;
    printf("Enter any number : ");
    scanf("%d",&num);

    switch(num)
    {
    case 1:
    {
       if(num>100 || num<0)
       {
         printf("Invalid number");
       }
         break;
       }

    case 2:
    {
        if(num>=80 && num<=100)
        {
         printf("A+");
        }

        break;
    }
    case 3:
    {
        if(num>=70 && num<=79)
      {
        printf("A");
      }
        break;
    }

    case 4:
    {
      if(num>=60 && num<=69)
      {
        printf("A-");
      }

        break;
    }

    case 5:
    {
        if(num>=50 && num<=59)
        {
         printf("B");
        }

        break;
    }


    case 6:
    {
        if(num>=40 && num<=49)
        {
         printf("C");
        }

        break;
    }

    case 7:
    {
        if(num>=32 && num<=39)
        {
          printf("D");
        }

        break;
    }

    default:

           printf("F");
    }
}

Solution

  • The variable num is used to switch on a range from 0 to 7 & default and a score between 0 and 100 & out of rang. It cannot be both at the same time. If you want to map a num to a grade I suggest you eliminate the switch.

    As num is checked from largest to smallest on contiguous range there is no need to check the lower bound. Note that num > 100 is the same as num >= 101. This makes each test the same other than the special case of negative scores. This will come handy below.

    Always check the return value of scanf() otherwise you may be operating on an uninitialized variable.

    #include <stdio.h>
    
    int main() {
        printf("Enter any number : ");
        int num;
        if(scanf("%d",&num) != 1) {
            printf("scanf failed\n");
            return 1;
        }
        if(num < 0 || num>=101)
            printf("Invalid number\n");
        else if(num>=80)
            printf("A+\n");
        else if(num>=70)
            printf("A\n");
        else if(num>=60)
            printf("A-\n");
        else if(num>=50)
            printf("B\n");
        else if(num>=40)
            printf("C\n");
        else if(num>=32)
            printf("D\n");
        else if(num >= 0)
            printf("F\n");
    }
    

    and example run:

    Enter any number : 40
    C
    

    Don't Repeat Yourself (DRY) is the next step, for example, by searching through a scale table for a score. This design makes it easy to update the scale, or even read it from a data file at run-time so you don't have to recompile the program if the scale changes:

    #include <stdio.h>
    
    struct scale {
        size_t n;
        int *score;
        char **grade;
    };
    
    const char *grade(struct scale *scale, int score) {
        for(size_t i = 0; i < scale->n; i++)
            if(score >= scale->score[i])
                return scale->grade[i];
        return scale->grade[0]; // score < 0
    }
    
    int main() {
        printf("Enter any number : ");
        int num;
        if(scanf("%d",&num) != 1) {
            printf("scanf failed\n");
            return 1;
        };
        struct scale scale = {
            8,
            (int []) {101, 80, 70, 60, 50, 40, 32, 0},
            (char *[]) {"Invalid number", "A+", "A", "A-", "B", "C", "D", "F"}
        };
        printf("%s\n", grade(&scale, num));
    }
    

    grade() could be implemented in terms of lfind() but there is little point to here:

    #include <search.h>
    
    int ge(const void *a, const void *b) {
        return *(int *) a >= *(int *) b ? 0 : 1;
    }
    
    const char *grade(struct scale *scale, int score) {
        int *offset = lfind(&score, scale->score, &scale->n, sizeof *scale->score, ge);
        return scale->grade[offset ? offset - scale->score : 0];
    }