Sida 1 av 1
Passa array av strukt till funktion i C? (Litet exempel)
Postat: 5 april 2014, 15:29:55
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.
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();
}
Re: Passa array av strukt till funktion i C?(Litet exempel)
Postat: 5 april 2014, 16:25:55
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.
Re: Passa array av strukt till funktion i C?(Litet exempel)
Postat: 5 april 2014, 18:47:04
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.
Re: Passa array av strukt till funktion i C?(Litet exempel)
Postat: 5 april 2014, 19:06:31
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/
Re: Passa array av strukt till funktion i C?(Litet exempel)
Postat: 6 april 2014, 00:24:56
av MiaM
Nog anses väl funktionen main vara aktiv även när main har anropat en annan funktion?
Re: Passa array av strukt till funktion i C?(Litet exempel)
Postat: 6 april 2014, 07:16:15
av blueint
Det är funktionen som anropas som detta avser.
Re: Passa array av strukt till funktion i C? (Litet exempel)
Postat: 7 april 2014, 00:34:36
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.
Re: Passa array av strukt till funktion i C? (Litet exempel)
Postat: 7 april 2014, 00:42:49
av Jennie
Åh tack så himla mycket allihopa! Fick till det nu.

Re: Passa array av strukt till funktion i C? (Litet exempel)
Postat: 7 april 2014, 00:44:35
av sodjan
Och problemet/felet var, vadå ??
Re: Passa array av strukt till funktion i C? (Litet exempel)
Postat: 7 april 2014, 02:08:01
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 ..

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