C按值查找字符串

C按值查找字符串,c,C,我需要将值转换为人类可读的字符串。通常,对于我定义的东西,我会使用从零开始的值,并创建一个简单的字符串数组,将这些值作为索引 static const char *foo[] = { "foo", "bar", "etc" }; if (val < 3) printf("%s\n", foo[val]); 从C99开始,您可以使用: 这相当于您发布的数组定义,将生成一个包含9个条目的数组。结构的初始化也有类似的语法: struct Person joe = { .name = "

我需要将值转换为人类可读的字符串。通常,对于我定义的东西,我会使用从零开始的值,并创建一个简单的字符串数组,将这些值作为索引

static const char *foo[] = { "foo", "bar", "etc" };
if (val < 3) printf("%s\n", foo[val]);
从C99开始,您可以使用:

这相当于您发布的数组定义,将生成一个包含9个条目的数组。结构的初始化也有类似的语法:

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

请注意,这只是一个C功能,如果没有太多的间隙,您可以将每个连续序列编码为一个单独的数组,然后进行少量边界检查以找到合适的数组。下面是一个简单的例子:

#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;
}
#包括
#包括
静态常量int数组_first_索引[]={3,15,28,32};
静态常量char*array0[]={“foo”};
静态常量char*array1[]={“bar”,“baz”};
静态常量char*array2[]={“bloop”、“blorp”、“blat”};
静态常量char*array3[]={“glop”、“slop”、“bop”};
#定义检查数组(whichArray,idx){\
无符号int relIdx=idx-数组的第一个索引[whichArray]\
if(relIdx<(sizeof(array###whichArray)/sizeof(const char*))\
返回数组##whichArray[relIdx]\
}
常量字符*lookupford(int-idx)
{
检查_数组(0,idx);
检查_阵列(1,idx);
检查_阵列(2,idx);
检查_阵列(3,idx);
返回NULL;
}
int main(int参数,字符**argv)
{

对于(int i=0;i创建一个将ID映射到字符串的排序数组,并使用
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;
}
#包括
#包括
结构id\u消息\u映射{
int-id;
字符常量*str;
};
int comp_id_字符串(const void*键,const void*元素)
{
int key_id=((结构id_msg_map*)key)->id;
int-element\u-id=((struct-id\u-msg\u-map*)元素)->id;
if(key\u idelement\u id)返回1;
返回0;
}
静态结构id_msg_map msg_map[]={
{3,“信息3”},
{12,“电文12”},
{100,“信息100”},
{32000,“信息32000”},
};
#定义(x)(sizeof(x)/sizeof((x)[0])的元素
字符常量*获取消息(整数x)
{
结构id_msg_映射键={x};
struct id_msg_map*msg=b搜索(&key,msg_map,元素(msg_map),sizeof(msg_map[0]),comp_id_字符串);
如果(!msg)返回“无效消息id”;
返回msg->str;
}
无效测试消息(int x)
{
printf(“ID为%d的消息:\%s\“\n”,x,get_msg(x));
}
内部主(空)
{
试验(0);
试验(3);
试验(100);
测试信号(-12);
返回0;
}
您可以使用指定的初始值设定器,如中所述,但这会悄悄地引入与前面提到的相同的间隙(使用隐式
0
值)。当您知道
0
永远不会成为实际选择时,该选项最合适,因为表不会动态更改(特别是大小)当桌子很小的时候


如果表特别大,但从未添加或删除项,则可以在键/值对样式的结构上使用和。例如:

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);
}
struct foo\u对{
int键;
字符*值;
};
int foo_pair_compare(void*x,void*y){
结构foo_对*a=x,*b=y;
返回(a->key>b->key)-(a->keykey);
}
内部主(空){
结构foo_pair foo[]={{.key=3,.value=“foo”},
{.key=5,.value=“bar”},
{.key=6,.value=“etc”};
/*qsort需要在项目开始时进行,
而且每次foo改变时*/
qsort(foo,sizeof foo/sizeof*foo,sizeof*foo,foo\u配对比较);
/*b搜索用于从排序数组中检索项*/
struct foo_pair*selection=b搜索(&(struct foo_pair){.key=5},
foo,sizeof foo/sizeof*foo,
sizeof*foo,foo\u对(比较);
}


当定期从集合中添加或删除项目时,选择哈希表或某种有序映射会更有意义。如果您不必费心编写和测试自己的这些集合,我想您可以在internet上查看大量经过测试的库。

这就是我一直在做的b但是,当引用我们没有定义的索引时,如您的示例中的4,它会返回null。我关心的是这种不安全的行为;这样可以吗,我只需要适当地处理null?是的,它是安全的。未初始化的值被初始化为null或零值,在您的示例中是
null
指针。间隙的处理方式与t相同未初始化的元素是:在
inta[3]={2,5};
a[2]
的值保证为0。(注意:我的建议只是对您的解决方案的一个更好的表示。它基本上创建了相同的数组,包括许多空条目。如果您需要一个带有索引值对的稀疏数组,您必须显式地实现它。)比我在这种情况下需要的稍微多一些,但我会将其归档。谢谢。
#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;
}
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);
}