Доступ к массиву структур через указатель - PullRequest
1 голос
/ 23 мая 2011

Здесь у меня есть определение структуры:

typedef struct person {
unsigned int ssn, age, height, weight, income;
char name[MAXS+1], job[MAXS+1], religion[MAXS+1], major[MAXS+1], minor[MAXS+1], gender;
}PERSON;

И здесь у меня есть массив функций типа PERSON:

    PERSON record[MAXR+1];

Как передать этот массив другой функции для обновления в реальном времени (т. Е. В качестве указателя)?

Моя интуиция и предыдущие знания подсказывают мне следующее:

PERSON *rp[MAXR+1];
for(i=0; i<MAXR; i++){
        *rp[i]=&record[i];
    }
valid=readfile(fp, rp);

Однако я получаю ошибку "несовместимые типы в присваивании". Как правильно это сделать?

Вот полный код:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAXS 19
#define MAXR 999

typedef struct person {
unsigned int ssn, age, height, weight, income;
char name[MAXS+1], job[MAXS+1], religion[MAXS+1], major[MAXS+1], minor[MAXS+1], gender;
}PERSON;


//get and check ssn
int getssn(){
int num;

printf("\nSSN: ");
scanf("%d", &num);

if(num<=99999999 || num>999999999){
    printf("\nPlease input a valid SSN.\n");
    return 0;
}
else
    return num;
}

int readfile(FILE *fptr, PERSON **rptr){
int v=0, i, j;

for(i=0; i<MAXR; i++){
    j=i;
    if(fscanf(fptr, "%c\n%d\n%19s\n%d\n%19s\n%d\n%19s\n%19s\n%d\n%d\n%19s\n\n",
          &rptr[j]->gender, &rptr[j]->ssn, rptr[j]->name, &rptr[j]->age, 
          rptr[j]->job, &rptr[j]->income, rptr[j]->major, rptr[j]->minor,
          &rptr[j]->height, &rptr[j]->weight, rptr[j]->religion)==EOF)
        i=MAXR;
    if(&rptr[MAXR]->ssn==&rptr[j]->ssn)
        v=j;
}


return v;
}

int main(){
int valid=0, i;
char filename[MAXS]="clients.txt";
FILE *fp;
PERSON record[MAXR+1], *rp[MAXR+1];

do{
    record[MAXR].ssn=getssn();
}while(record[MAXR].ssn==0);

printf("Name of file of records: ");
//gets(filename);

if((fp=fopen(filename, "r"))==NULL)
    printf("\nCould not open file\n");
else{
    printf("\njur doing gohd\n");
    for(i=0; i<MAXR; i++){
        *rp[i]=&record[i];
    }
    valid=readfile(fp, rp);
    if(valid==0){
        printf("\nSSN %d is not found in file %s.\n", record[MAXR].ssn, filename);
    }
    else {
        printf("%d", valid);
    }
}



return 0;
}

Ответы [ 4 ]

2 голосов
/ 23 мая 2011

Вы пытаетесь присвоить адрес переменной PERSON фактической переменной PERSON (не address), которую вы, вероятно, намеревались сделать:

rp[i]=&record[i];

Обратите внимание, что он будет копировать указатель на структуру, а не саму структуру. Если вы хотите скопировать структуру, вам нужно использовать memcpy или memmove

0 голосов
/ 24 мая 2011

Массивы не могут быть переданы непосредственно в функции - если вы попытаетесь, он просто передает указатель на первый элемент массива (который может быть проиндексирован так же, как и сам массив, для доступа к любому члену массива). Вот почему вы можете услышать, что массивы «передаются по ссылке» - хотя технически это не , это эффект.

Итак, все, что вам нужно сделать, это объявить вашу функцию следующим образом:

int readfile(FILE *fptr, PERSON rptr[])
{
    int v = 0, i;

    for(i = 0; i < MAXR; i++) {
        if (fscanf(fptr, "%c\n%d\n%19s\n%d\n%19s\n%d\n%19s\n%19s\n%d\n%d\n%19s\n\n",
          &rptr[i]->gender, &rptr[i]->ssn, rptr[i]->name, &rptr[i]->age, 
          rptr[i]->job, &rptr[i]->income, rptr[i]->major, rptr[i]->minor,
          &rptr[i]->height, &rptr[i]->weight, rptr[i]->religion) < 11)
            break;

        if (rptr[MAXR]->ssn == rptr[i]->ssn)
            v = i + 1;
    }

    return v;
}

... и вы можете напрямую назвать это так:

valid = readfile(fp, record);

В rp вообще нет необходимости.

0 голосов
/ 23 мая 2011

Стоит также указать на круглые скобки, неявные в fptr [i] -> job.Это (* fptr) [i], а не * fptr [i] или * (fptr [i]).То есть вы хотите индексировать после того, как вы последуете за указателем, а не до.

0 голосов
/ 23 мая 2011

вам просто нужно:

int readfile(FILE *fptr, PERSON *rptr);

Массив - по определению - это просто одноуровневый указатель на структуру, которую вы определили.

int readfile(FILE *fptr, PERSON *rptr){
int v=0, i, j;

for(i=0; i<MAXR; i++){
    j=i;
    if(fscanf(fptr, "%c\n%d\n%19s\n%d\n%19s\n%d\n%19s\n%19s\n%d\n%d\n%19s\n\n",
          rptr[j]->gender, rptr[j]->ssn, rptr[j]->name, rptr[j]->age, 
          rptr[j]->job, rptr[j]->income, rptr[j]->major, rptr[j]->minor,
          rptr[j]->height, rptr[j]->weight, rptr[j]->religion)==EOF)
        i=MAXR;
    if(rptr[MAXR]->ssn==rptr[j]->ssn)
        v=j;
}

нет необходимости указателя на указатель, потому что вы объявляете массив вне функции. Если вы делаете malloc для выделения памяти внутри функции, то вам нужен указатель на указатель, чтобы вернуть указатель на выделенную память - но не ваш случай.

...