Научиться правильно ссылаться на поле структуры при использовании scanf (C) - PullRequest
0 голосов
/ 14 октября 2019

Я создал эту структуру

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

Кроме того, я объявил эти переменные и указатель

dadosPessoais dp[4], *dpp;

В настоящее время я пытаюсь получить некоторые данные отuser и использует указатель * dpp для хранения этих данных в переменной dp []. Чтобы сделать это, я сделал эту структуру цикла

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

Я знаю, что использование что-то вроде dpp->field некорректно при использовании scanf, так как оператор стрелки (->) используется для возврата структурызначение поля, используя адрес этой структурной переменной, и оно не используется для возврата самого адреса структурного поля. Но если я попытаюсь использовать что-то вроде dpp.field, оно все равно не будет работать, что сбивает с толку, поскольку оно должно означать что-то вроде &dp[index].field, верно? Я до сих пор не понял, как решить эту проблему ...

Ответы [ 2 ]

2 голосов
/ 14 октября 2019

После выполнения dpp = &dp[i];, dpp указывает на экземпляр struct dadosPessoais. Тогда dpp->cep относится к cep члену этого struct, а &dpp->cep - это адрес этого члена. Таким образом, чтобы передать адрес члена cep в scanf, передайте &dpp->cep.

При использовании scanf с %s вы должны передать адрес первого символа в массиве,Таким образом, для dpp->nome вы можете передать &dpp->nome[0].

Однако, поскольку nome является массивом, он будет автоматически преобразован в указатель на его первый элемент при использовании его в выражении. 1 Таким образом, вы можете использовать пропуск dpp->nome до scanf, и он будет аналогичен пропуску &dpp->nome[0].

Сноска

1 Это автоматическое преобразование не происходит, когда массив является операндом sizeof, является операндом унарного оператора & (который принимает адрес) или является строковым литералом, используемым для инициализации массива. В частности, обратите внимание, что &array и array являются указателями, но тип &array является «указателем на массив», тогда как array после автоматического преобразования является указателем на элемент массива.

0 голосов
/ 14 октября 2019

Правильный способ сделать это должен быть scanf ("% s", dpp-> nome). Пример:

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

В C массивы будут указывать адрес памяти своего первого элемента. Вот почему, когда вы делаете что-то вроде этого:

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

nome уже является ссылкой на начало массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...