使用用户变量访问struct成员

时间:2013-05-20 12:34:42

标签: c struct

让我假设我有一个结构如下:

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);
}

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

5 个答案:

答案 0 :(得分:3)

C不支持任何可以轻松开始工作的运行时反射。我怀疑你能做的最好的事情就是编写一个编写字符串到结构成员选择函数的代码生成器。

答案 1 :(得分:1)

在输入运行时性能方面,最有效的编码方法可能是使用gperf

基本上,您键入所需的名称列表,以及要映射到的名称列表(数组索引,变量指针等),它将为您生成C代码。

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

以下是一些现实代码中的示例:   conf.c   confitems.gperf

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

答案 2 :(得分: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 */
}

它非常依赖于你了解结构的布局。

这可以形成你可以做的一些切换的基础知识,以提取各种结构成员。

虽然并不好,但很难维护。即使在结构发生微小变化之后,你也会崩溃。

答案 3 :(得分:0)

我只是好奇你如何解释这一行

i = person.argv[1];

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

无论如何......您必须解释传递给程序的参数,并根据输入的内容显示您希望从结构中获取的数据。你必须区分映射用户输入 - >数据 - 显示。

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]);
    }
}

如果您引用reflection,我认为C

不可能

答案 4 :(得分: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);
            }
        }
    }
}