0

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();
}
1

4 Answers 4

2

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;
}
Sign up to request clarification or add additional context in comments.

7 Comments

awesome! This is what I want !
It is a feature of the language that you can copy a struct with the = assignment, but not an array (unless it is contained within the struct).
One more question is added to my edited question: "if the pass mark of each subject is 35,print the name of the students that failed in all 4 subjects". I replace my previous code with yours and added an extra code to answer this new question. But it shows "No one fails" even if someone fails. You may kindly check my edited program in the question. What may be the cause?
Because you are checking marks in four subjects but you only entrered data for three. The fourth element of the array s[i].marks[3] is uninitialised, because struct student s[sno]; is a local variable, and you never write a value to that element.
A thousand times better than my memcpy approach. +1
|
1

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

Comments

1

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

Comments

1

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

1 Comment

thank you for your answer, my up vote for all of you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.