Passa array av strukt till funktion i C? (Litet exempel)

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Jennie
Inlägg: 173
Blev medlem: 8 februari 2014, 13:23:00

Passa array av strukt till funktion i C? (Litet exempel)

Inlägg av Jennie »

Hej på er! Skulle behöva lite hjälp här! :)

Jag försöker i princip göra som i det här exemplet här nedan.
Dock vill jag försöka få det att fungera i ett slags menystyrt program så att det ska gå att välja om man vill skriva in datan där (void accept) eller om man vill skriva ut det som man tidigare skrev in (void print).

Nu ligger båda i void main men jag undrar om man kan dela upp void main på något vis och kanske göra en switch där det står printf"För att skriva in tryck 1: " och sen en annan printf"För att skriva ut tryck 2: ".
Har prövat fram och tillbaka och ibland när det verkar som jag lyckas så skriver den ut, men helt fel siffror än vad jag satte in i structs-arrayen. :cry:

Kod: Markera allt

#include<stdio.h>
#include<conio.h>
//-------------------------------------
struct student
{
  int age;
  int points;
}s[3];
//-------------------------------------
void accept(struct student sptr[],int n)
{
  int i;
  for(i=0;i<n;i++)
  {
  printf("\nEnter age : ");
  scanf("%d",&sptr[i].age);
  printf("\nEnter points : ");
  scanf("%d",&sptr[i].points);
  }
}
//-------------------------------------
void print(struct student sptr[],int n)
{
  int i;
  for(i=0;i<n;i++)
  {
  printf("\nNum1 : %d",sptr[i].age);
  printf("\nNum2 : %d",sptr[i].points);
  }
}
//-------------------------------------
void main()
{
int i;
clrscr();
accept(s,3);
print(s,3);
getch();
}
Senast redigerad av Jennie 5 april 2014, 16:40:01, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26628
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Passa array av strukt till funktion i C?(Litet exempel)

Inlägg av Icecap »

Först vill jag rekommendera att du gör en type:

Kod: Markera allt

typedef struct
  {
  int age;
  int points;
  } T_STUDENT;
Då kan du deklarera:
T_STUDENT S[3];

För att sedan jobba med datan måste du ha en "klump" att jobba med. Om du deklarerar direkt i en rutin kommer de data att vara "borta"/återvunna när rutinen lämnas.

Sedan kan du jobba:

Kod: Markera allt

void accept(T_STUDENT* sptr[], int n)
  {
  int i;
  for(i = 0; i < n; i++)
    {
    printf("\nEnter age : ");
    scanf("%d", sptr[i]->num1);
    printf("\nEnter points : ");
    scanf("%d", sptr[i]->points);
    }
  }
//-------------------------------------
void print(T_STUDENT* sptr[], int n)
{
  int i;
  for(i=0;i<n;i++)
  {
  printf("\nNum1 : %d",sptr[i]->age);
  printf("\nNum2 : %d",sptr[i]->points);
  }
}
Tagit ur huvudet utan garanti för funktionalitet.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Passa array av strukt till funktion i C?(Litet exempel)

Inlägg av blueint »

Ändrade i koden och testade med GCC att det fungerar: stud03.c

Kod: Markera allt

#include<stdio.h>
#include<conio.h>
/*-------------------------------------*/
struct student
{
  int age;
  int points;
};

/*-------------------------------------*/
void accept(struct student *sptr, int n)
{
  int i;
  printf("%u-%10s: %p\n", __LINE__, "accept", sptr); fflush(stdout);

  for(i=0; i<n; i++)
  {
  printf("\nEnter age : ");
  scanf("%d", &(sptr->age) );
  printf("\nEnter points : ");
  scanf("%d", &(sptr->points) );
  sptr += sizeof(struct student);
  }
}
/*-------------------------------------*/
void print(struct student *sptr, int n)
{
  int i;
  for(i=0; i<n; i++)
  {
  printf("\nNum1 : %d", sptr->age );
  printf("\nNum2 : %d", sptr->points );
  sptr += sizeof(struct student);
  }
}
/*-------------------------------------*/
int main()
{
int i;
struct student sdata[3];

clrscr();
accept(&sdata, 3 );
print(&sdata,  3 );
getch();
return 0;
}
För den som vill använda unixmiljö så behöver man ändra och lägga till följande:

Kod: Markera allt

//#include<conio.h>
int clrscr(){ return 0; }
int getch(){ return 0; }
Det borde dock gå att använda följande funktionsdeklaration:
void accept(struct student *sptr[], int n)

Och sedan fylla i den med sptr->age osv..
Dels verkar pekaren hamna helt fel till själva strukturen (*sptr) och istället för att mata fram pekaren med storleken på strukturen (8 bytes) så matas den fram med storleken för en pekare (4 bytes). Iofs är det rätt självklart med tanke på att "*sptr[]" är en lista med pekare så det kanske är en metod som jag minns fel..
Poängen är att man slipper manuell hantering av pekaren och kan ha en ren definition av programmet.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Passa array av strukt till funktion i C?(Litet exempel)

Inlägg av blueint »

Tekniken som visas på sidan 6 utav 6 i dokumentet lect20.pdf är kanske det som uppgiftsskaparen efterfrågar.

Kod: Markera allt

Student readRecord ( Student newStudent )
{
printf("Enter last name and mark: ");
scanf("%s %f",newStudent.lastname,&(newStudent.mark));
return newStudent;
}

main()
{
Student studentA;
studentA = readRecord(studentA);
}
Notera att den returnerade strukturen lever rätt farligt om jag minns det rätt i och med att den bara är giltig när funktionen är aktiv (typen "auto"?).

Edit: Finns en del intressanta kursgenomgångar här: csse.monash.edu.au/courseware/../lect/
Användarvisningsbild
MiaM
Inlägg: 12760
Blev medlem: 6 maj 2009, 22:19:19

Re: Passa array av strukt till funktion i C?(Litet exempel)

Inlägg av MiaM »

Nog anses väl funktionen main vara aktiv även när main har anropat en annan funktion?
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Passa array av strukt till funktion i C?(Litet exempel)

Inlägg av blueint »

Det är funktionen som anropas som detta avser.
Användarvisningsbild
kimmen
Inlägg: 2042
Blev medlem: 25 augusti 2007, 16:53:51
Ort: Stockholm (Kista)

Re: Passa array av strukt till funktion i C? (Litet exempel)

Inlägg av kimmen »

Fast nu är det väl så att koden i originalinlägget är korrekt och fungerar, så när som på att att void som returtyp från main() är icke-standard. Men det tillåts ändå i många implementationer.

> Notera att den returnerade strukturen lever rätt farligt om
> jag minns det rätt i och med att den bara är giltig när funktionen är aktiv (typen "auto"?).

Den kopieras både in och ut ur funktionen i ditt exempel. Inget problem alls. Det är om man returnerar en pekare till en lokal variabel som det kan gå riktigt illa.

Den där tidigare koden med sptr += sizeof(struct student); gör nog inte heller vad du förväntar dig, för += matar inte fram ett antal bytes, utan ett antal element. Det du har skrivit matar alltså fram pekaren sizeof(struct student) * sizeof(struct student) antal bytes för varje varv. Med lite otur så kanske det råkar verka fungera för att det man skrev sönder inte var tillräckligt viktigt...

Sen om man skickar in parametern som struct student sptr[] eller struct student * sptr gör detsamma. Båda fungerar likadant. Icecaps T_STUDENT* sptr[] (ekvivalent med T_STUDENT ** spt) betyder dock något helt annat och är nog inte vad som önskades här - och se upp med scanf som vill ha pekare till typerna som specifieras av formatsträngen.

Men vad var egentligen frågan? Det var väl koden som var skrivet på ett annat sätt än den som postades som inte fungerade? Det hade nog varit lättare att hitta problemet om koden som inte fungerade hade varit den som postades.
Jennie
Inlägg: 173
Blev medlem: 8 februari 2014, 13:23:00

Re: Passa array av strukt till funktion i C? (Litet exempel)

Inlägg av Jennie »

Åh tack så himla mycket allihopa! Fick till det nu. :)
sodjan
EF Sponsor
Inlägg: 43245
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Passa array av strukt till funktion i C? (Litet exempel)

Inlägg av sodjan »

Och problemet/felet var, vadå ??
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Passa array av strukt till funktion i C? (Litet exempel)

Inlägg av blueint »

kimmen skrev:Den där tidigare koden med sptr += sizeof(struct student); gör nog inte heller vad du förväntar dig, för += matar inte fram ett antal bytes, utan ett antal element. Det du har skrivit matar alltså fram pekaren sizeof(struct student) * sizeof(struct student) antal bytes för varje varv. Med lite otur så kanske det råkar verka fungera för att det man skrev sönder inte var tillräckligt viktigt...
Så jag hade tur mao .. :vissla:
Men med en typecast (int) så att det blir ett hopp i antal bytes vore det korrekt? alternativt att man använder en struct student *sptr pekare som man inkrementerar med sptr++ så att pekaren inkrementeras implicit med längden av en (struct student).
(en alternativ typecast är att använda (void *)sptr += sizeof(struct student); )
Skriv svar