Larger than and less than in C switch statement
Asked Answered
H

8

34

I'm trying to write a code that has a lot of comparison

Write a program in “QUANT.C” which “quantifies” numbers. Read an integer “x” and test it, producing the following output:

x greater than or equal to 1000 print “hugely positive”
x from 999 to 100 (including 100) print “very positive”
x between 100 and 0 print “positive”
x exactly 0 print “zero”
x between 0 and -100 print “negative”
x from -100 to -999 (including -100) print “very negative”
x less than or equal to -1000 print “hugely negative”

Thus -10 would print “negative”, -100 “very negative” and 458 “very positive”.

Then I tried to solve it using a switch statement, but it didn't work. Do I have to solve it using an if statement or there is a method to solve it using a switch statement?

#include <stdio.h>

int main(void)
{
    int a=0;
    printf("please enter a number : \n");

    scanf("%i",&a);

    switch(a)
    {
        case (a>1000):
            printf("hugely positive");
            break;

        case (a>=100 && a<999):
            printf("very positive");
            break;

        case (a>=0 && a<100):
            printf("positive");
            break;

        case 0:
            printf("zero");
            break;

        case (a>-100 && a<0):
            printf("negative");
            break;

        case (a<-100 && a>-999):
            printf("very negative");
            break;

        case (a<=-1000):
            printf("hugely negative");
            break;

    return 0;
}
Histo answered 7/1, 2014 at 12:59 Comment(3)
switch can only handle exact comparisons with constant integral values. You'll have to use if and else.Drolet
Seven compiling errors should have told you something (and 1 warning: control reaches end of non-void function).Protomartyr
In your problem definition it is not mentioned to use only switch case. if else is way to go!Reluctivity
F
22

There is no clean way to solve this with switch, as cases need to be integral types. Have a look at if-else if-else.

Fanjet answered 7/1, 2014 at 13:3 Comment(0)
P
15

A switch-less and if-else-less method:

#include <stdio.h>

int main(void)
{
    int a=0, i;
    struct {
        int value;
        const char *description;
    } list[] = {
        { -999, "hugely negative" },
        { -99, "very negative" },
        { 0, "negative" },
        { 1, "zero" },
        { 100, "positive" },
        { 1000, "very positive" },
        { 1001, "hugely positive" }
    };

    printf("please enter a number : \n");
    scanf("%i",&a);

    for (i=0; i<6 && a>=list[i].value; i++) ;
    printf ("%s\n", list[i].description);

    return 0;
}

The for-loop contains no code (there is just an empty statement ;) but it still runs over the array with values and exits when the entered value a is equal to or larger than the value element in the array. At that point, i holds the index value for the description to print.

Protomartyr answered 7/1, 2014 at 13:20 Comment(4)
I'll be grateful if you explained it step by step, thanks anywayHisto
The for loop is all that matters -- use a debugger, or go through it with pen and paper. Well, that, and a consistent handling of the equality operators in your list of descriptions.Protomartyr
Just stumbled on this topic and found this answer. Solution doesn't work if the entered number is lower than -999Ingathering
@AlexG: there is no description for values less than the minimum value, and adding one requires adding a borderline value for that in turn. Perhaps all it needs is INT_MIN instead of that arbitrary -999. (Similar, I see, to anatolyg's answer using INT_MAX to force a cap off on the other end.)Protomartyr
T
8

If you are using gcc, you have "luck" because it supports exactly what you want by using a language extension:

#include <limits.h>
...

switch(a)
{
case 1000 ... INT_MAX: // note: cannot omit the space between 1000 and ...
    printf("hugely positive");
   break;
case 100 ... 999:
    printf("very positive");
   break;
...
}

This is non-standard though, and other compilers will not understand your code. It's often mentioned that you should write your programs only using standard features ("portability").

So consider using the "streamlined" if-elseif-else construct:

if (a >= 1000)
{
    printf("hugely positive");
}
else if (a >= 100)
{
    printf("very positive");
}
else if ...
...
else // might put a helpful comment here, like "a <= -1000"
{
    printf("hugely negative");
}
Tombolo answered 7/1, 2014 at 13:20 Comment(1)
Why will other compilers not understand the using of ellipses in a switch statement (causing a "non-standard") ?Stanza
D
3

(a>1000) evaluates to either 1 [true] or 0 [false].

Compile and you will get the error:

test_15.c:12: error: case label does not reduce to an integer constant

This means, you have to use an integer constant value for the case labels. An If-else if-else loop should work just fine for this case.

Dark answered 7/1, 2014 at 13:4 Comment(2)
a>1000 evaluates to boolean not integral 1 or 0.Fanjet
@EricFortin No: "Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int."Rosauraroscius
P
2

Use:

switch (option(a)) {
    case (0): ...
    case (1): ...
    case (2): ...
    case (n): ...

Where the option() function is simply a function with if else.

It lets you keep the clean look of a switch and the logic part is elsewhere.

Posterior answered 21/12, 2017 at 15:5 Comment(0)
C
1

Comments on the OP's code:

  1. Return code from scanf() is not tested to assure valid input.
  2. scanf("%i"...) will mysteriously convert from octal or hexadecimal. Use %d instead. RTFM.
  3. Much cited: the values of case labels are not compile time integer types.
  4. case (a>1000): would, if it worked, have missed a being exactly 1000.
  5. case (a>=0 &&... overlaps the range of case 0:. Sloppy work!

For entertainment, the following code goes a step beyond the OP's challenge with two extra categorisations (that could be deleted to give the OP's desired output.) A silly bit of code that forms a nice output.

#include <stdio.h>

void eval( int v ) {
    printf( "%7d - ", v );
    if( v == 0 )
        puts( "zero" );
    else {
        int deg = 0, isneg = v < 0;

        while( deg < 4 && (v /= 10) != 0 ) deg++;

        char *adj = "";
        switch( deg ) { // "switch" used, as requested by OP
            case 4: adj = "tremendously "; break; // added
            case 3: adj = "hugely "; break;
            case 2: adj = "very "; break;
            case 1: adj = "eh, "; break; // added
        }
        printf( "%s%stive\n", adj, isneg ? "nega" : "posi" );
    }
}

int main( void ) {
    for( int p = 100000; p; p /= 10 ) eval( p );
    eval( 0 );
    for( int n = -1; n >= -100000; n *= 10 ) eval( n );

    return 0;
}

Result:

 100000 - tremendously positive
  10000 - tremendously positive
   1000 - hugely positive
    100 - very positive
     10 - eh, positive
      1 - positive
      0 - zero
     -1 - negative
    -10 - eh, negative
   -100 - very negative
  -1000 - hugely negative
 -10000 - tremendously negative
-100000 - tremendously negative
Cordalia answered 18/11, 2023 at 21:11 Comment(2)
IMO you should replace the outer "tremendously" with something like "stupendously" or even better "soooper stupendously" as that would extend your "off-center hourglass" motif in your output. ;-)Rosauraroscius
@AndrewHenle "soooper stupendously"?? :-) Could borrow from Douglas Adams... "vastly, hugely, mind-bogglingly..." :-)Cordalia
L
0

Why do you have a preference to use switch?

I'm asking because this sounds awfully like a 'homework question'. A compiler should deal with if/else construct just as efficiently as a switch (even if you weren't dealing with ranges).

Switch can't handle ranges as you have shown, but you could find a way to include switch by categorising the input first (using if/else) then using a switch statement to output the answer.

Largess answered 7/1, 2014 at 13:7 Comment(0)
A
0
int a=0;
printf("please enter a number : \n");
scanf("%i",&a);
switch(a>1000)
{
    case (1):
        printf("hugely positive");
        break;
}

In this situation switch case can be used as shown above

Achaemenid answered 18/11, 2023 at 14:45 Comment(1)
How can this address the OP's actual issue, which is that they have a large number of tests? Your code will only allow one possible test per switch block.Cheapskate

© 2022 - 2024 — McMap. All rights reserved.