获取基于成员值的结构

时间:2017-04-05 01:58:01

标签: c struct

我有一个庞大的struct数组,我创建了不同的函数来根据成员的值获取结构指针:

int result;
while (true) {
    try {
        Scanner scan = new Scanner(System.in);
        input = scan.next();
        result = Integer.parseInt(input);
    } catch(Exception e) {
        System.out.println("Could not parse input, please try again.");
        continue;
    }

    if (result != 1 && result != 2) {
        System.out.println("Invalid input! Please select '1' or '2':");
    }
    else {
        break;
    }
}

有没有一种简单的方法可以在C中解决这个问题,而不是为每个成员创建一个查找函数?

1 个答案:

答案 0 :(得分:0)

以下是编写通用函数以获取(查找)第一个匹配的struct成员的一种方法。

我尝试与您的示例代码保持一致,添加了一些可能必需的#include指令,以及#define的典型固定数组TEST_SIZE,这样您就不会# 39; t对循环索引使用硬编码值。

#include <stddef.h>
#include <stdio.h>
#include <string.h>

typedef struct {
    uint32_t a;
    uint32_t b;
    uint32_t c;
    uint32_t d;
} test_t;

test_t test[10]; // Initialized somewhere else
#define TEST_SIZE (sizeof(test)/sizeof(test[0]))

static test_t* __get_struct_by_offset(const void* value_ptr, const size_t offset, const size_t field_size)
{
    for (uint32_t i = 0; i < TEST_SIZE; i++)
    {
        if (0 == memcmp(value_ptr, ((unsigned char*)&test[i])+offset, field_size))
        {
            return &test[i];
        }
    }
    return NULL;
}

您可以这样使用它:

    uint32_t a_value_to_find = 5; /* example field "a" value to find */
    uint32_t b_value_to_find = 10; /* example field "b" value to find */
    test_t* test_ptr;

    /* find specified value for field "a" */
    test_ptr = __get_struct_by_offset(&a_value_to_find, offsetof(test_t, a), sizeof(a_value_to_find));

    /* find specified value for field "b" */
    test_ptr = __get_struct_by_offset(&b_value_to_find, offsetof(test_t, b), sizeof(b_value_to_find));

您有责任确保*value_ptr的数据类型和指定offset的字段相同,因此大小相同(field_size)。

为简化用法,您可以编写一些宏作为这些调用的简写。例如:

#define GET_A(value) __get_struct_by_offset(&value, offsetof(test_t, a), sizeof(value))
#define GET_B(value) __get_struct_by_offset(&value, offsetof(test_t, b), sizeof(value))

&#34; a&#34;的查询和&#34; b&#34;然后简化为:

    /* find specified value for field "a" */
    test_ptr = GET_A(a_value_to_find);

    /* find specified value for field "b" */
    test_ptr = GET_B(b_value_to_find);