C search string by value

I need to translate the value into a human readable string. Usually for the things that I define, I would use values ​​starting from zero and creating a simple array of strings with values ​​as an index.

static const char *foo[] = { "foo", "bar", "etc" };
if (val < 3) printf("%s\n", foo[val]);

For this circumstance, I have values ​​that do not start from zero, and there are gaps between them. Is there a good way to do this without having to manually encode empty rows for indexes without the corresponding value / row pair?

static const char *foo[] = { "", "", "", "foo", "", "bar", "", "", "etc" };
+4
source share
4 answers

Starting with C99, you can use designated initializers :

static const char *foo[] = { 
   [3] = "foo", 
   [5] = "bar",
   [8] = "etc"
};

This is equivalent to a computed array definition and will generate an array with 9 elements. Similar syntax for initializing structures:

struct Person joe = {
    .name = "Joe", .age = 24, .favcolor = "mauve"
};

, C ++.

+7

, , , . :

#include <stdio.h>
#include <stdlib.h>

static const int array_first_indices[] = {3, 15, 28, 32};
static const char * array0[] = {"foo"};
static const char * array1[] = {"bar", "baz"};
static const char * array2[] = {"bloop", "blorp", "blat"};
static const char * array3[] = {"glop", "slop", "bop"};

#define check_array(whichArray, idx) { \
   unsigned int relIdx = idx - array_first_indices[whichArray]; \
   if (relIdx < (sizeof(array##whichArray)/sizeof(const char *))) \
      return array##whichArray[relIdx]; \
   }

const char * LookupWord(int idx)
{
   check_array(0, idx);
   check_array(1, idx);
   check_array(2, idx);
   check_array(3, idx);
   return NULL;
}

int main(int args, char ** argv)
{
   for (int i=0; i<50; i++) printf("   LookupWord(%i) = %s\n", i, LookupWord(i));
   return 0;
}

, , , ​​ - ; C , , ++, , .

+3

, bsearch() :

#include <stdio.h>
#include <stdlib.h>

struct id_msg_map {
    int id;
    char const* str;
};


int comp_id_string( const void* key, const void* element)
{
    int key_id     = ((struct id_msg_map*) key)->id;
    int element_id = ((struct id_msg_map*) element)->id;

    if (key_id < element_id) return -1;
    if (key_id > element_id) return  1;
    return 0;
}

static struct id_msg_map msg_map[] = {
    {3, "message 3"} ,
    {12, "message 12"},
    {100, "message 100"},
    {32000, "message 32000"},
};

#define ELEMENTS_OF(x) (sizeof(x) / sizeof((x)[0]))
char const* get_msg(int x)
{
    struct id_msg_map key = {x};
    struct id_msg_map* msg = bsearch(&key, msg_map, ELEMENTS_OF(msg_map), sizeof(msg_map[0]), comp_id_string);

    if (!msg) return "invalid msg id";

    return msg->str;
}

void test_msg(int x)
{
    printf("The message for ID %d: \"%s\"\n", x, get_msg(x));
}

int main(void)
{
    test_msg(0);
    test_msg(3);
    test_msg(100);
    test_msg(-12);
    return 0;
}
+1

, M. Oehm, , ( 0). , , 0 , ( ) .


, , qsort bsearch / . :

struct foo_pair {
     int key;
     char *value;
};

int foo_pair_compare(void *x, void *y) {
    struct foo_pair *a = x, *b = y;
    return (a->key > b->key) - (a->key < b->key);
}

int main(void) {
    struct foo_pair foo[] = { { .key = 3, .value = "foo" },
                              { .key = 5, .value = "bar" },
                              { .key = 6, .value = "etc" } };

    /* qsort needs to be done at the start of the program,
       and again each time foo changes */
    qsort(foo, sizeof foo / sizeof *foo, sizeof *foo, foo_pair_compare);

    /* bsearch is used to retrieve an item from the sorted array */
    struct foo_pair *selection = bsearch(&(struct foo_pair) { .key = 5 },
                                         foo, sizeof foo / sizeof *foo,
                                         sizeof *foo, foo_pair_compare);
}

When items are usually added or removed from the collection, it makes sense to choose a hash table or some sort of ordered map. If you cannot worry about writing and testing your own collections, I think there are many tried and tested libraries on the Internet that you could check.

0
source

Source: https://habr.com/ru/post/1589127/


All Articles