2

假设我有一个结构如下:

struct person {
    int age;
    char name[24];
} person;

并且用户给出程序应该读取哪个结构成员的参数。./program age

int main(int argc, char **argv) {
    int i;
    i = person.argv[1];
    printf("%i\n", i);
}

这显然是不可能的。有没有一种方法可以读取结构成员而无需在代码中输入确切的成员名称?我能想到的唯一方法是将给定的字符串与以每个结构成员命名的字符串进行比较。

4

5 回答 5

3

C 不以任何方式支持运行时反射,这会使它易于工作。我怀疑你能做的最好的事情就是编写一个代码生成器来编写字符串到结构成员选择函数。

于 2013-05-20T12:40:31.033 回答
1

就打字和运行时性能而言,最有效的编码方式可能是使用gperf

基本上,您输入您想要的名称列表,以及您想要映射到的内容(数组索引、变量指针等),它会生成 C 代码来为您执行此操作。

唯一的问题是您必须先学习如何使用它。

这是一些真实世界代码的示例: conf.c confitems.gperf

请注意,gperf 文件将字符串映射到 C 宏,因此程序员可以将他们喜欢的任何内容放入该宏中,甚至可以在不同的地方将其用于不同的目的。然后 C 文件包含生成的代码,并调用生成的函数confitems_get进行映射:字符串输入,宏内容输出。

于 2013-05-20T13:07:15.150 回答
0

你可以在行上写一个函数

char* getTheNameMemberOut(person* p)
{
   int* dodgy = (int*)(void*)(p);
   return (char*)(dodgy + 1); /* use pointer arithmetic to pass over the first member of the structure */
}

它在很大程度上依赖于您了解结构的布局。

这可以构成一些转换的基础,您可以进行一些转换以提取各种结构成员。

虽然不好,而且很难维护。即使结构发生微小变化,您也会崩溃。

于 2013-05-20T12:43:46.273 回答
0

我只是好奇你如何解释这条线

i = person.argv[1];

argv尝试使用 struct 访问它与您的结构有什么关系.

无论如何...您必须解释传递给程序的参数,并根据输入的内容从结构中显示您想要的数据。您必须定义映射用户输入-> 数据显示。

argv++; // move to the next pointer, since argv[0] always points to the excutable's name

if(*argv) {
    switch(*argv[0]) {
        case 'a':
            printf("age\n");
        break;
        case 'n':
            printf("name\n");
        break;
        default:
            printf("%c is no valid input\n", *argv[0]);
    }
}

如果您指的是反射,那么我认为这是不可能的C

于 2013-05-20T12:49:32.377 回答
0

您可以在这里使用一些输入处理和指针操作,我测试了以下代码并且效果很好。

int main(int argc, char **argv) {
    int i;
    thePerson.age = 1;
    strcpy(thePerson.name, "John Doe");
    if(argv[1] != NULL){
        int cmp = strcmp(argv[1], "age");
        if (cmp == 0){
            int* pAge = (int*)&thePerson;
            printf("%i\n", *pAge);
        }
        else{
            cmp = strcmp(argv[1], "name");
            if (cmp == 0){
                char* pName = (char*)(&thePerson)+sizeof(int);
                printf("%s\n", pName);
            }
        }
    }
}
于 2013-05-20T12:55:15.637 回答