0

I want myprogram to take user-entered arguments and see if each argument matches a hard-coded list. I am looking for a better alternative to a long switch statement or a series of if else.

Here is a minimal example of what I'm attempting using enum:

$ ./myprogram blue square

//myprogram.c
#include<stdio.h>

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

  //many allowable colors and shapes
  enum colors_t {blue, red, /*...*/ green}; 
  enum shape_t {square, circle, /*...*/ triangle};

  //how do I check if argv[1] is on the list of colors?
  if(COMPARE(argv[1], colors_t)
    colors_t user_color = argv[1];
  else 
    printf("%s is not a usable color\n",argv[1]);

  //same question with shapes
  if(COMPARE(argv[2], shape_t)
    shape_t user_shape = argv[2];
  else  
    printf("%s is not a usable shape\n",argv[2]);

  return 0;
}

I need help with the COMPARE() function to see if argv[i] matches a member of its corresponding enum list.

user1717828
  • 7,122
  • 8
  • 34
  • 59
  • 1
    A loop and an array maybe... – IKavanagh Aug 22 '15 at 21:05
  • possible duplicate of [Easy way to use variables of enum types as string in C?](http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c) – wimh Aug 22 '15 at 21:07

1 Answers1

1

One way to do this would be to use qsort and bsearch (well, if you don't mind making sure the array is sorted yourself, you don't need qsort). Something like (using your enum color_t):

struct color_picker {
    char const *name;
    enum colors_t id;
} acolor[] = { {"blue", blue}, {"red", red}, {"green", green} };
const unsigned acolor_count = sizeof acolor / sizeof acolor[0];

int cmp_color(struct color_picker const *l, struct color_picker const *r)
{
    return strcmp(l->name, r->name);
}

int main(int argc, char *argv[])
{
    struct color_picker *ptr;

    qsort(acolor, acolor_count, sizeof acolor[0], cmp_color);

    ptr = bsearch(name, acolor, acolor_count, sizeof acolor[0], cmp_color);
    if (NULL == ptr) {
        printf("%s is not a usable color\n",argv[1]);        }
    }
    /* the value for `enum color_t` is in `ptr->id` */

    return 0;
}

You could also use hash tables here, but there is not support for those in the C standard library, so you'd have to code it yourself, or use some third-party library.

srdjan.veljkovic
  • 2,468
  • 16
  • 24
  • I didn't use your solution, but I've upvoted and marked as accepted since you were the only one nice enough to answer. – user1717828 Oct 28 '15 at 16:24