1

I want to use bsearch with array of const chars in order to determine index in this array. Here is the code:

enum _command {dodaj, koniec, usun, wczytaj, wczytajwszystko, zapisz, zapiszwszystko};
const char *_command_s[] = {"dodaj", "koniec", "usun", "wczytaj", "wczytajwszystko", "zapisz", "zapiszwszystko"};
int
const_strcmp(const void *s1, const void *s2) {
    const char *key = s1;
    const char * const *arg = s2;
    return strcmp(key, *arg);
}

int main() {
char *pcommand. command[100];/*and other vars*/
pcommand = (char *)bsearch(command, _command_s, COUNT(_command_s), \
            sizeof(char *), (int (*)(const void *, const void *))const_strcmp);


if (pcommand == NULL) 
        fputs_state = fputs(PROMPT, stdout);
else {
    switch ((enum _command)((pcommand - (char *)_command_s)/sizeof(char *))) {
        case dodaj:
        (do something)

It's working on GNU/Linux/gcc but I'm not sure is it ANSI standards-compliant and would it work properly on others compilers. Do you think I can use this this way or maybe you have any better proposals for solving this task.

alk
  • 69,737
  • 10
  • 105
  • 255
ghi
  • 697
  • 2
  • 9
  • 20
  • 1
    you have 4 variables with very similar names. This is job security 101. – egur Dec 02 '13 at 07:30
  • 1
    Your indirection in your comparator is wrong. You're being handed the *address* of `char*` elements, thus they're not single-indirection; they're double. The first one specifically in incorrect. For some reason you did it right with the second. – WhozCraig Dec 02 '13 at 07:38
  • You shouldn't need that ugly cast in the call to `bsearch()`. Your function pointer is of the correct type so the cast is a no-op — or a drag on the readability of your code. Also, names starting with underscore are basically reserved for 'the implementation'. You're not creating 'the implementation' (you'd know if you were) so you should avoid names that start with `_`. The `switch ((enum _command)((pcommand - (char *)_command_s)/sizeof(char *)))` ugliness is also unnecessary if you use the correct type `char **pcommand`; you can then do `switch (pcommand - command_s)`. – Jonathan Leffler Dec 02 '13 at 07:42
  • Thanks for your advises. Now I have: switch((enum db_command)(pcommand - db_command_s)). I've left enum cast because I think that makes the code more understandable. Is it right to do or it's uncommon in C programs? – ghi Dec 02 '13 at 07:58

1 Answers1

1

A few things:

  • compare func arguments are actually const char**, you treat one of them wrong (key).
  • bsearch returns const char** in this case. So pcommand should be const char** and accessed/printed as *pcommand.
  • you call bsearch with an uninitialized variable as the first parameter (command).
  • Using so many variables with similar names is confusing to say the least. At least prefix the globals with g or g_.

Your code seems standard compliant.

egur
  • 7,830
  • 2
  • 27
  • 47