简体   繁体   English

学习如何在使用 scanf (C) 时正确引用结构字段

[英]Learning how to properly reference to a struct field when using scanf (C)

I've made this struct我做了这个结构

struct dadosPessoais
{
    char nome[60];
    char end[60];
    char cidade[60];
    char estado[3];
    int cep;
};
typedef struct dadosPessoais dadosPessoais

Also, I've declared these variable and pointer另外,我已经声明了这些变量和指针

dadosPessoais dp[4], *dpp;

What I'm currently trying to do is receive some data from user and using *dpp pointer in order to store this data within dp[] variable.我目前正在尝试做的是从用户接收一些数据并使用 *dpp 指针将这些数据存储在 dp[] 变量中。 To do it, I've made this loop structure为此,我制作了这个循环结构

for (i = 0; i < 4; i++)
{
    dpp = &dp[i];
    printf("-- Dados da %da pessoa --\n", i + 1);
    printf("Nome: ");
    scanf("%s", dpp->nome);
    getchar();
    printf("Endereço: ");
    scanf("%s", dpp->end);
    getchar();
    printf("Cidade: ");
    scanf("%s", dpp->cidade);
    getchar();
    printf("Estado: ");
    scanf("%s", dpp->estado);
    getchar();
    printf("Cep: ");
    scanf("%d", dpp->cep);
    getchar();
    system("clear");
}

I know that using something like dpp->field is not correct when using scanf, since the arrow operator (->) is used to return a struct field value by using the address of that struct variable and it's not used to return the struct field address itself.我知道在使用scanf时使用dpp->field类的东西是不正确的,因为箭头运算符(->)用于通过使用该结构变量的地址来返回结构字段值,而不是用于返回结构字段解决自己。 But if I try to use something like dpp.field it still doesn't work, what is confusing since it supposed to mean something like &dp[index].field , right?但是,如果我尝试使用类似dpp.field之类的东西,它仍然无法正常工作,因为它应该意味着类似&dp[index].field .field 的东西,这有什么令人困惑的,对吧? I still doesn't figured out how to solve this problem...我仍然不知道如何解决这个问题......

After dpp = &dp[i];dpp = &dp[i]; is executed, dpp points to an instance of the struct dadosPessoais .执行时, dpp指向struct dadosPessoais的一个实例。 Then dpp->cep refers to the cep member of that struct , and &dpp->cep is the address of that member.然后dpp->cep指的是该structcep成员,而&dpp->cep是该成员的地址。 So, to pass the address of the cep member to scanf , pass &dpp->cep .因此,要将cep成员的地址传递给scanf ,请传递&dpp->cep

When using scanf with %s , you should pass the address of the first character in the array.scanf%s一起使用时,您应该传递数组中第一个字符的地址。 So, for dpp->nome , you could pass &dpp->nome[0] .因此,对于dpp->nome ,您可以通过&dpp->nome[0]

However, since nome is an array, it will be automatically converted to a pointer to its first element when you use it in an expression.但是,由于nome是一个数组,当您在表达式中使用它时,它会自动转换为指向其第一个元素的指针。 1 So, you can use pass dpp->nome to scanf , and it will be the same as passing &dpp->nome[0] . 1因此,您可以使用 pass dpp->nomescanf ,它与传递&dpp->nome[0]相同。

Footnote脚注

1 This automatic conversion does not occur when the array is the operand of sizeof , is the operand of the unary & operator (which takes the address), or is a string literal used to initialize an array. 1当数组是sizeof的操作数、一元&运算符(获取地址)的操作数或用于初始化数组的字符串文字时,不会发生这种自动转换。 Note in particular that &array and array are pointers, but the type of &array is “pointer to array,” whereas array , after automatic conversion, is a pointer to an element of the array.特别注意&arrayarray是指针,但是&array的类型是“指向数组的指针”,而array自动转换后是指向数组元素的指针。

The proper way to do it should be scanf("%s", dpp->nome).正确的做法应该是 scanf("%s", dpp->nome)。 Example:例子:

#include <stdio.h>

struct test {
     char a[10];
};

int main() {
     struct test new_struct_array[1];
     struct test * ptr = &new_struct_array[0];
     scanf("%s", ptr->a);
     printf("%s", ptr->a);
     return 0;
}

In C, arrays will point to the memory address of their first element.在 C 中,arrays 将指向其第一个元素的 memory 地址。 That is why when you do something like this:这就是为什么当你做这样的事情时:

char nome[10];
scanf("%s", nome);  // works
scanf("%s", &nome); // does not

nome is already a reference to the start of the array. nome已经是对数组开头的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM