Reputation: 1417
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
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
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
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
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