使用用户变量访问结构体成员

3

假设我有一个以下结构体:

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

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


是的!使用一个集成开发环境(IDE)并让IDE为您完成吧!您只需要点击一下来选择成员名称... - undefined
2
不,你不能这样做。如果有人输入错误,该怎么办呢?无论如何,你都需要检查输入的正确性,因此在进行检查时,也可以输入成员名称。 - undefined
5个回答

3

C语言没有支持运行时反射的机制,这使得实现此功能变得困难。我猜测你最好的选择是编写一个代码生成器,用于生成字符串到结构体成员选择函数。


1

在编程中,既要考虑输入效率,也要考虑运行效率,最有效的方法可能是使用gperf

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

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

这里有一个来自实际代码的示例: conf.c confitems.gperf

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

看起来真的很强大。我会去看一下的。 - undefined

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 */
}

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

这可以形成一些切换的基础,您可以使用它来提取各种结构成员。

虽然不太好且难以维护。即使在结构发生小变化后,您也会遇到崩溃。


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语言中是不可能的。

我从来没有说过我的代码有任何意义^^ 我只是想说明我的需求是什么。你的答案和我所考虑的类似。其他的答案也指向了同样的方向。 - undefined
@Hans,我知道,而且你自己也说了,但我就是忍不住要问一下,抱歉。但有时候用伪代码或散文来解释会更好,真正的代码可能会误导人们思考和猜测“他想做什么”或者“他知道自己在做什么吗”,而前者则是“我想要做这个和那个” :-) - undefined
我明白你的意思,很有道理。下次我会尝试使用伪代码。 - undefined

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

@Hasturkun 是的,我承认这一点,但由于C语言不支持反射,我们应该找到解决问题的方法,不是吗? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接