Parveez Ahmed
Parveez Ahmed

Reputation: 1417

Sorting array of structure with members as arrays

Problem:- write a c program to accept names and marks of 10 students in 4 subjects and print the rank list in ascending order of average of marks in 4 subjects.Print individual marks for each student.if the pass mark of each subject is 35,print the name of the students that failed in all 4 subjects.

The Algorithm adopted is:-

1.Start
2.Get student name and marks in 4 subjects
3.Calculate average for each student
4.Sort average in acsending order
5.Swap student names in the same order as average
6.Swap student marks in the same order as average
7.Display rank list
8.Display individual marks for each student
9.Stop

My Question:- I have written the following program only to stumble at the step 6 of the algorithm. Is there any approach to accomplish step 6?

#include<stdio.h>
#include<conio.h>
#include<string.h>
#define sub 3
#define sno 3
struct student
{
  char sname[20];
  int avg,marks[4];
};
void main()
{
  int i,j,max,bit=0;
  char swapname[20];
  struct student s[sno];
  clrscr();
  for(i=0;i<sno;i++)
  {
   printf("Enter the name of student %d:",i+1);
   scanf("%s",s[i].sname);
   printf("Enter marks in four subjects\t");
   for(j=0;j<sub;j++)
   {
    scanf("%d",&s[i].marks[j]);
   }
   //initialize structure member
   s[i].avg=0;
   //compute average
   for(j=0;j<sub;j++)
   {
    s[i].avg+=s[i].marks[j];
   }
   s[i].avg/=sub;
  }//FOR LOOP ends
  printf("\n\n");
  //Displaying failed students
  printf("List of the failed students:\n");
  for(i=0;i<sno;i++)
  {
   if(s[i].marks[0]<35&&s[i].marks[1]<35&&s[i].marks[2]<35&&s[i].marks[3]<35)
   {
    printf("%s\n\n",s[i].sname);
    if(bit==0)
     bit=1;
   }
  }
  if(bit==0)
   printf("No one fails!\n\n");
  //SORTING
  for(i=0;i<sno;i++)
  {
   for(j=i+1;j<sno;j++)
   {
    if(s[i].avg>s[j].avg)
    {
     max=s[i].avg;
     s[i].avg=s[j].avg;
     s[j].avg=max;
     strcpy(swapname,s[i].sname);
     strcpy(s[i].sname,s[j].sname);
     strcpy(s[j].sname,swapname);

    }
   }
  }
  //Display result
  printf("Student Name in the ascending order of Average obtained:\n");
  for(i=0;i<sno;i++)
  {
    printf("%s:\t",s[i].sname);
    printf("%d\n",s[i].avg);
  }

  getch();
}

Upvotes: 0

Views: 120

Answers (4)

Weather Vane
Weather Vane

Reputation: 34585

You can do steps 5 and 6 all in one go by swapping the entire struct.

if(s[i].avg > s[j].avg)
{
    struct student temp = s[i];
    s[i] = s[j];
    s[j] = temp;
}

Upvotes: 2

Enzo Ferber
Enzo Ferber

Reputation: 3094

I think that changing the way you are sorting is better. Since you store everything in a struct element, you can swap the whole element instead of individual fields.

I don't know if the algorithm you provided is a homework constraint or if you came up with it. I'm considering the latter. To swap two elements of the struct, I used a temporary variable and the memcpy function. Here's the commented code:

...

struct student s[sno], tmp;

...

/* Sorting:
 *
 * Since everything is stored in the @s struct, you can swap
 * the elements of the struct itself, that simplifies the code.
 */
for (i = 0; i < sno; i++) {
    for (j = i + 1; j < sno; j++) {
        if (s[i].avg > s[j].avg) {
            /* backup copy */
            memcpy(&tmp, &s[i], sizeof tmp);

            /* swap elements */
            memcpy(&s[i], &s[j], sizeof tmp);

            /* restore the copy */
            memcpy(&s[j], &tmp, sizeof tmp);
        }
    }
}

Upvotes: 1

ReshaD
ReshaD

Reputation: 946

First you should change the int avg to fload avg. Then after swapping the names you can use another for loop to do the swapping of the marks. it's easier because you don't need to use any function and you can just use a temporary variable:

int tmpMark, k;
for (k=0; k<sub; k++){
   tmpMark=s[i].marks[k];
   s[i].marks[k] = s[j].marks[k];
   s[j].marks[k] = temp;
}

Upvotes: 1

Cherubim
Cherubim

Reputation: 5457

Just use an extra temporary variable in a loop to swap all the marks of two students, just like you used swapname to swap names

 strcpy(swapname,s[i].sname);//Swap student names
 strcpy(s[i].sname,s[j].sname);
 strcpy(s[j].sname,swapname);

 for(int index = 0; index < 4; index++) //swapping student marks
 {
     int temp = s[i].marks[index];
     s[i].marks[index] = s[j].marks[index];
     s[j].marks[index] = temp;
 }

Tip: Next time when you encounter a problem such as this(swapping all the values of an array) try using loops

Upvotes: 1

Related Questions