LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-20-2006, 07:36 AM   #1
mic
Member
 
Registered: Jun 2005
Posts: 44

Rep: Reputation: 16
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?
 
Old 02-20-2006, 08:02 AM   #2
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
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.
 
Old 02-20-2006, 08:09 AM   #3
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
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.
 
Old 02-20-2006, 08:47 AM   #4
mic
Member
 
Registered: Jun 2005
Posts: 44

Original Poster
Rep: Reputation: 16
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.
 
Old 02-20-2006, 09:19 AM   #5
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
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");
        }
    }



}
 
Old 02-20-2006, 09:43 AM   #6
mic
Member
 
Registered: Jun 2005
Posts: 44

Original Poster
Rep: Reputation: 16
Thanks, funny output by the way (yuk )

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?
 
Old 02-21-2006, 11:02 AM   #7
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,187

Rep: Reputation: 354Reputation: 354Reputation: 354Reputation: 354
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
enum inheritance in C++? graemef Programming 2 01-27-2006 10:14 PM
HOTSWAP: where to find #ENUM signal? iflorea Programming 0 11-20-2005 06:58 AM
C Enum exvor Programming 3 09-27-2005 02:51 PM
C, enum confusion cigarstub Programming 2 09-27-2005 09:59 AM
invalid types int[int] for array subscript scuzzman Programming 2 11-16-2004 09:34 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:43 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration