我是C语言的新手,我尝试使用“for”将数据插入到结构体中,如下所示:
char *personAttributes[6] = {"cpf", "name", "sex", "dtBorn", "city", "UF"};
int i;
Person pw;
typedef struct
{
char cpf;
char name;
char sex;
int dtBorn;
char city;
char UF;
} Person;
for (i = 0; i < 6; i++)
{
printf("Input person's %s: \n", personAttributes[i]);
scanf("%[^\n]", &pw.personAttributes[i]);
}
而不是在多行中阅读每个结构属性(结构的每个元素一行,如:...,&pw.cpf,&pw.name...),我想动态地完成它,通过在for中传递参数,并通过数组中的索引访问它。
我试着这样做:
scanf("%[^\n]", &pw.personAttributes[i]);
但是这种访问方式显然不起作用。2有没有什么方法可以在C语言中做类似的事情?
3条答案
按热度按时间rkttyhzu1#
(edit:其他海报让我想起了让这变得人性化得多的offsetof macro)
C不会自动知道如何去做,你希望你的程序在运行时知道Person的属性是什么(“cpf”、“name”等)。然而,当你用C编程时,你的程序并不知道这些。编译器知道调用了什么,但它不会将这些信息存储在编译后的程序中。在Python这样的动态语言中,编译器和你的程序之间的分离就更少了,你可以做这样的事情,但是在C语言中,你写的就是你得到的。
然而,这仍然可以通过一些额外的工作来实现。你只需要显式地告诉你的程序它需要知道什么。你的程序需要知道每个属性的名称是什么,如何读取它,以及它在结构体中的存储位置。由于编译器不会自动将这些信息存储在你的程序中,你需要显式地将其存储在你的代码中,如下所示:
现在,
attributes
常量包含了所有额外的信息,对于每个属性,它记住了属性名、属性的scanf
字符串以及从Person
结构体开始到属性所在位置的偏移量(这是offsetof
宏为我们计算的;https://en.wikipedia.org/wiki/Offsetof有更多关于这方面的信息)。现在,我们已经在
attributes
中保存了我们需要的额外信息。即使在运行时,我们的程序也有存储的信息来做你想做的事情。我们只需要显式地使用它,如下所示:当我们编译并运行程序时,我们将得到:
您的问题很清楚,但您应该注意原始版本中存在的一些问题:
cpf
、name
等都是单个字符,而不是字符串(字符数组)。我不知道“cpf”和“UF”是什么,但我假设您希望name、city和Sex是字符串。" %79[^\n]s"
中的79
)。这使得有人可以通过输入比您预期更长的字符串来破坏或利用您的程序。请查看http://www.crasseux.com/books/ctutorial/String-overflows-with-scanf.html以了解有关此问题的更多讨论。我知道这些可能是出于你的目的和意图,但以防万一他们不是:
6
),参见https://en.wikipedia.org/wiki/Magic_number_(programming)了解更多关于这个编程规则的信息。看起来你犯了每个人在第一次学习C语言时都会犯的错误。但是你想做的事情是可行的,也是合理的,我希望这能帮助你交流如何做。你可能想在花更多的时间思考指针数学之后再回到这个问题上来,这取决于你的舒适程度。但是不用担心!你很快就会学会的。
fumotvh32#
没有办法使用字符串数组来迭代结构体的成员(因为成员的名称通常只在编译时可用)。你可以使用每个成员的(标识符)名称来获得指向每个成员的指针,但这不会保存你的任何努力。如果你需要迭代,请使用数组,或者你可以编写函数来访问值数组的正确位置。
另外,struct的一些成员类型为
char
(单个字母),可能应该是char *
(字符串)。bfnvny8b3#
没有简单的方法来实现这一点,C语言也没有对类似操作的直接支持。如果你用元素的名称,
offsetof()
和sizeof
每个成员的名称构建一个表,你可以模糊地接近它。(offsetof
宏在<stddef.h>
中定义。)但是存在如何编码每个成员的类型的问题,你可以编写适合于你的结构所使用的类型的代码,但是很难使它完全通用--因为结构可以是任意多样的。看看这两个问题,寻找一些想法-但没有简单的方法来处理它:
offsetof
on a struct?C23将引入两个新的关键字-
typeof
和typeof_unqual
(参见p114上的N3054 §6.7.2.5 Typeof specifiers)。现在还不清楚它们是否可以用于支持这一点。它们是语言中的类型说明符,在预处理器完成很久之后才生效(所以我不认为您能够将结果转换为字符串;字符串化是一个预处理器操作,但typeof
可能只能由主编译器而不是预处理器来计算)。