LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Check if an int value is within valid range of enum? (https://www.linuxquestions.org/questions/programming-9/check-if-an-int-value-is-within-valid-range-of-enum-417500/)

mic 02-20-2006 07:36 AM

Check if an int value is within valid range of enum?
 
Suppose I have defined an enum:
Code:

enum myEnum {
  VAL_A = 0;
  VAL_B = 2;
  VAL_C = 10;
  VAL_D = 12;
  VAL_E = 25;
  VAL_F = 30;
};

Then I read an int value from file or stdin. How do I verify that it is one of the valid values of that enum? Of course I don't mean to do something like
Code:

if (value != VAL_A && value != VAL_B && value != VAL_C ....)
Is there any nice and clean way at all?

bigearsbilly 02-20-2006 08:02 AM

well, you could use an int array of valid values.
Iterate and check.

but then you'd still need to hard-code the values twice if you wanted the enums
which leaves room for bugs.

can't think of a neat way meself keeping the enums.

PTrenholme 02-20-2006 08:09 AM

Well, first, how would your input stream creator know what values had been used in your enumeration type? In other words, why would you be using an enumeration type to parse an input stream?

The obvious solution would be to set up an array, initialize it to your enumeration values, sort it, and do a binary search to find a match, if any. Note, however, that there is no restriction on the values assigned to enumeration types, so, for example, this is a perfectly valid enumeration:
Code:

enum myEnum {
  VAL_A = 0;
  VAL_B = 0;
  VAL_C = -100;
  VAL_D = 1;
  VAL_E = 2;
  VAL_F = -100;
};

so finding the input value in your enumeration does not, in fact, tell you wich specific enumeration value was intended as the input.

So, again, I don't think you should compare any data stream with an enumeration type. Just use a array of valid input values and search it.

Aside: If you're using C++, there are several templates in the standard template library to make this problem fairly easy.

mic 02-20-2006 08:47 AM

I'm using enum for a config option. If this option has some weird value, the program would not function properly. I use switch sentences for handling these options, so the program eventually finds out the value is wrong, but this could happen only when the switch block gets executed, which could be after a long time. I'd like to warn user of this shortly after the program is started.

I'm writing in C, not C++.

The user knows which numbers are valid, but there is always a possibility of a human mistake or config file corruption ...

Quote:

The obvious solution would be to set up an array, initialize it to your enumeration values, sort it, and do a binary search to find a match
Could you please explain this in more details, perhaps some example code? I don't know how to:

1) Determine what length should that array have. I don't know how to get the enum length, sizeof(anyEnum) returns 4.

2) Initialize that array to enum values. Without explicitly naming every value of course.

bigearsbilly 02-20-2006 09:19 AM

noddy example:
Code:

#include <stdio.h>

static int valid[] = { 3, 9, 12, 77 };

int is_valid(int test)
{
    int *p=valid;
    int * limit = (p + sizeof valid);

    for (; p < limit; p++) {
        if (*p == test) {
            return 1;
        }
    }
    return 0;
}

int main(int argc, char ** argv)
{
    int test;

    for(++argv ; --argc; argv++) {

        sscanf(*argv, "%d", &test);
        printf("%d:", test);

        if ( is_valid (test)) {
            puts("OK");
        } else {
            puts("Yuk");
        }
    }



}


mic 02-20-2006 09:43 AM

Thanks, funny output by the way (yuk:D )

It is however, not exactly what I meant. I need enum, because after I'd read and check the value, I'd like to operate only with labels, not numbers and not arrays, because labels tell you much more.

I'd like to declare all values only in enum. Then I would use for example something like you suggested, but all the values and length of array should be determined automatically so I will have to change only the enum definition when I decide to change/add/remove an option. Is this possible in C?

PTrenholme 02-21-2006 11:02 AM

Have you considered using struct instead of enum?

This code seems to work:
Code:

$ cat test5.c
#include <stdio.h>
static struct myEnum {
  int A;
  int B;
  int C;
  int D;
  int E;
  int F;
} Val = {0, 2, 10, 12, 25, 30};

int main(int argc, char ** argv)
{
  int test;
  printf("sizeof(Val)=%d\nsizeof(Val.A)=%d\n", sizeof(Val), sizeof(Val.A));
  for (test = 0; test < sizeof(Val)/sizeof(Val.A); ++test) {
    printf("test %d Val = %d\n",test, *(&Val.A+test));
  }
}
$ ./test5
sizeof(Val)=24
sizeof(Val.A)=4
test 0 Val = 0
test 1 Val = 2
test 2 Val = 10
test 3 Val = 12
test 4 Val = 25
test 5 Val = 30

And your references would look almost the same: Val.A instead of Val_A.

It gets a little trickier if not all your struct elements are the same type, but remains, I think, workable.


All times are GMT -5. The time now is 01:22 AM.