C, Как получить доступ к структуре из другой структуры? - PullRequest
1 голос
/ 28 января 2011

Я получаю ошибку:

error: request for member ‘clsf_ptr’ in something not a structure or union

Из этой программы на C:

#include<stdio.h>
#define M 3

struct class_stud
{
    char name[16];
    char subject[16];
    int roll_num;
}

struct node
{
    int n;
    struct branch *p[M];
    struct class_stud cls[M-1];
}*root=NULL;

main()
{
    int clsf_cnt;
    struct class_stud clsf, *clsf_ptr;
    clsf_ptr = &clsf;
    clsf_cnt = 0;
    root = malloc(sizeof (struct node));
    printf("enter source address \n");
    scanf("%s",&root.clsf_ptr[clsf_cnt]->name);
    printf("%s",root.clsf_ptr[clsf_cnt]->name);

    printf("enter key\n");
    scanf("%d",&root.clsf_ptr[clsf_cnt]->key);
    printf("%d",root.clsf_ptr[clsf_cnt] -> key);
    clsf_cnt++;
}

Что означает ошибка?

Ответы [ 5 ]

3 голосов
/ 28 января 2011

В этом коде есть ряд проблем. Давайте пройдемся по нему строка за строкой:

#include<stdio.h>     
#define M 3      

struct class_stud     
{     
  char name[16];     
  char subject[16];     
  int roll_num;     
}      

Первая проблема; вам нужно закрытие ; после определения структуры выше. Кроме того, интересно, что вы не определяете макрос препроцессора для длин массивов name и subject, но на данный момент это незначительная проблема.

struct node     
{     
  int n;     
  struct branch *p[M];     
  struct class_stud cls[M-1];     
}*root=NULL;        

Где определение для struct branch? Что p должно представлять в определении структуры? Почему у вас в cls меньше элементов, чем p?

main()

Начиная с C99, вы не можете избежать использования неявного типа для main; он должен быть явно набран для возврата int. И, поскольку вы не возитесь с какими-либо аргументами командной строки, лучше явно установить список параметров на void, например:

int main(void)
{     
  int clsf_cnt;     
  struct class_stud clsf, *clsf_ptr;     
  clsf_ptr = &clsf;     

Какую цель выполняет вышеуказанная операция?

  clsf_cnt = 0;     
  root = malloc(sizeof (struct node)); 

Это хорошо, но предпочтительный способ написания этого будет

  root = malloc(sizeof *root);

Таким образом, вы обязательно выделите правильный объем памяти в зависимости от типа root.

  printf("enter source address \n");     
  scanf("%s",&root.clsf_ptr[clsf_cnt]->name);     

Ack. Несколько проблем в одной строке.

Прежде всего, clsf_ptr является , а не членом struct node. Вы, вероятно, хотели получить доступ к cls. Во-вторых, поскольку root является указателем на структуру, вам нужно использовать оператор -> для доступа к его членам (или явно разыменовать root, а затем использовать .). В-третьих, cls[clsf_cnt] - это , а не тип указателя, поэтому вы должны использовать оператор . для доступа к name. Наконец, поскольку name является типом массива, он будет неявно преобразован в тип указателя перед передачей в scanf, поэтому & не требуется.

Чтобы избежать переполнения буфера, вы должны либо указать максимальную ширину поля в спецификаторе преобразования %s, либо использовать fgets() вместо scanf().

Придерживаясь scanf(), эта строка должна быть записана как

  scanf("%15s", root->cls[clsf_cnt].name);

Я использую 15 вместо 16 в спецификаторе преобразования, поэтому мы оставляем один символ для терминатора 0.

Используя fgets (), эта строка будет написана

  fgets(root->cls[clsf_cnt].name, sizeof root->cls[clsf_cnt].name, stdin);
  printf("%s",root.clsf_ptr[clsf_cnt]->name);     

Опять же, вы пытаетесь получить доступ к тому, что не является членом root, и у вас есть операторы доступа назад:

  printf ("%s", root->cls[clsf_cnt].name);

  printf("enter key\n");     
  scanf("%d",&root.clsf_ptr[clsf_cnt]->key);     
  printf("%d",root.clsf_ptr[clsf_cnt] -> key);

struct class_stud не имеет члена с именем key; возможно вы имели ввиду roll_num?

  scanf("%d", &root->cls[clsf_cnt].roll_num);
  printf("%d", root->cls[clsf_cnt].roll_num);    
  clsf_cnt++;     
} 

Похоже, вы опубликовали что-то не завершенное; убедитесь, что вы показываете тот же код, который пытаетесь создать.

1 голос
/ 28 января 2011

Любой экземпляр root.clsf_ptr, который есть в вашем коде, должен быть заменен на root->clsf_ptr, что указывает на то, что root является указателем на структуру.

Вам также необходимо убедиться, что член clsf_ptr находится в структуре node.

1 голос
/ 28 января 2011

Вот некоторая общая очистка исходного кода, которая может быть полезна:

#include <stdio.h>
#define M 3

typedef struct
{
  char  name [16];
  char  subject [16];
  int   roll_num;

} Class_stud;


typedef struct
{
  int         n;
  Branch*     p[M];
  Class_stud  cls[M-1];

} Node;



int main()
{
  Node*        root;
  int          clsf_cnt;
  Class_stud   clsf;
  Class_stud*  clsf_ptr;

  clsf_ptr = &clsf;
  clsf_cnt = 0;

  root = malloc (sizeof(Node));

  if(root == NULL)
  {
    /* error handling here */
  }
}
0 голосов
/ 28 января 2011

Следующий код должен работать для вас.Я предполагаю, что key должен быть членом в class_stud (и с вашими параметрами форматирования в scanf, целое число со знаком):

#include<stdio.h>
#define M 3

typedef struct
{
    char name[16];
    char subject[16];
    int roll_num;
    int key;
} class_stud;

typedef struct
{
    int n;
    struct branch *p[M];
    struct class_stud cls[M-1];
} node;

int main(void)
{
    int clsf_cnt = 0;
    node *root;

    root = malloc(sizeof(node));
    if (root == NULL) {
       /* handle error */
    }

    printf("enter source address \n");
    scanf("%s",&root->cls[clsf_cnt]->name);
    printf("%s",root->cls[clsf_cnt]->name);

    printf("enter key\n");
    scanf("%d",&root->cls[clsf_cnt]->key);
    printf("%d",root->cls[clsf_cnt]->key);
    clsf_cnt++;
}

У вас были следующие проблемы:

  • Неправильный доступ к class_stud.Это часть root, поэтому вы хотите, чтобы root -> class_stud [member] -> value.
  • key был опущен
  • Обе были изменены на структуры, определяемые типом, как показано в Lundin's ответ, однако вам не нужно делать их типами (достаточно просто использовать struct).
  • Мы просто объявляем root как указатель на узел, а не объявляем структурный узел, а затем указатель и затем выполняем присваивание.
  • Мы не создаем структуру как указатель,мы создаем указатель на структуру
  • Main должен возвращать тип int, если вам не нужны аргументы, скажите компилятору, что вы ожидаете, что argc будет недействительным.

Вещи, которые я не делал:

  • Инициализировать выделенную структуру с помощью memset () или через calloc ()
  • Обрабатывать malloc () не удалось
  • Скомпилировать мойпример (я не знаю, что такое struct branch)
0 голосов
/ 28 января 2011

Я думаю, что синтаксис malloc неправильный. один раз проверь это. Память не выделена. Вот почему она показывает ошибку.

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