I got an assignment to create a program to sort 10 students' data by grade (and if they have the same grade sort by name) using selection sort only(can't use any other method) in an ascending order. My problem is I can sort their grades using selection just fine but I'm having problems sorting the names of students with the same grades, i can use bubble for that but it's not allowed..if anyone could help me out it would be great

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>




struct {
 
int score;
char name1[20];
} lol[50];

int main()
{
	int temp;
	int a;
	float xy;
	char sigh[50];
	
	int arr[] = {2,7,2,9,2,5,13,9,2,22};
	char name[50][50] = {"andy","lala","boy","alfred","kurt","shelly","andriy","cooper","chris","scarlet"};
	for (int f = 0;f<10;f++){
		strcpy (lol[f].name1,name[f]);
		lol[f].score = arr[f];
	}
	puts ("before sorting");
	for (int f = 0;f<10;f++){
	printf ("%s %d\n",lol[f].name1,lol[f].score);
	}

	for (int x = 0;x<10;x++){
		temp = x;
		for (a = x+1;a<10;a++){
			if (lol[a].score < lol[temp].score ){
			temp = a;
			}
		}

		if (temp!=x){
		xy = lol[x].score;
		lol[x].score = lol[temp].score;
		lol[temp].score = xy;

		strcpy(sigh,lol[x].name1);
		strcpy(lol[x].name1,lol[temp].name1);
		strcpy(lol[temp].name1,sigh);
		}
	}

	for (int x = 1;x<10;x++){
		
		for (a =0;a<9;a++)
		{
      if (lol[a].score == lol[a+1].score )
	  {
		  if (strcmp(lol[a].name1,lol[a+1].name1)>0)
		  {
			strcpy(sigh,lol[a].name1);
			strcpy(lol[a].name1,lol[a+1].name1);
			strcpy(lol[a+1].name1,sigh);
	  }
		}
		
			}
		}
	


	puts("\n");
	puts ("after sorting: ");
		for (int f = 0;f<10;f++){
		printf ("%s %d\n",lol[f].name1,lol[f].score);
		}
	

	getch();
}

What happens if you put the grade and the name together in the same string, then sort?

Edited 4 Years Ago by thines01: typo

You can intercahnge struct variable directly.
Eg:
struct temp;
temp=lol[a];
loa[a]=lol[temp];
lol[temp]=lol[a];

This many not be the solution but you can try this

The solution to your problem is to use the memcmp function as a comparison of your structures. I do realize that this is somewhat of an unorthodox solution. But it does work. I did put together some proof of concept code to verify that it does in fact work. Unfortunately, I can't post any sample code. Otherwise I'll get more "demerits" from a mod.

But to reiterate, using memcmp will resolve your problem.

Good luck.

The solution to your problem is to use the memcmp function as a comparison of your structures. I do realize that this is somewhat of an unorthodox solution. But it does work. I did put together some proof of concept code to verify that it does in fact work. Unfortunately, I can't post any sample code. Otherwise I'll get more "demerits" from a mod.

But to reiterate, using memcmp will resolve your problem.

Good luck.

Padding can wreak havoc on that solution. See this link for details.

Padding can wreak havoc on that solution. See this link for details.

Well, I believe that author from that link should preface his work with a detailed explanation of compiler architecture and structure optimization. He is using a poorly optimized structure as follows:

struct my_buf {
  char buff_type;
  size_t size;
  char buffer[50];
};

He will have three bytes of padding between buff_type and size not to mention additional padding at the end of buffer. Since size is an unsigned int which must be 4 byte aligned, it can only appear at byte boundaries that are multiples of 4. Thus, the reason for the 3 bytes of padding. In this example it would definitely not be wise to use memcmp because of all the padding.

But let's look at the OP's structure:

struct {
 int score;
char name1[20];
} lol[50];

The above example has no padding since score starts at the very beginning of the structure and starts on a byte boundary which is a multiple of four. Also, note that name1 size is a multiple of 4. Thus no padding is needed and using memcmp is perfectly acceptable.

But let us just say that we are stuck with that ugly structure. How could we use memcmp with that structure which contains padding? Well, the MS compiler would use pragma commands. For example,

#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */

As indicated the current alignment is pushed to the stack and we are now using 1 byte boundaries. Thus, eliminating all the packing in that ugly structure. Since padding is now eliminated, we can use memcmp etc. without any issues. BTW, just about every C, C++ has this capability to work on the 1 byte boundary. Also, this is common practice in a lot of network applications where you may have to transmit/receive ugly structures using the various protocols.

Again, IMHO, the author should have provided the background info on compiler architecture, structure optimization. Not to mention that padding should be avoided at all costs. It's a drain on CPU utilization and a waste of memory resources.

Well, I believe that author from that link should preface his work with a detailed explanation of compiler architecture and structure optimization. He is using a poorly optimized structure as follows:

struct my_buf {
  char buff_type;
  size_t size;
  char buffer[50];
};

He will have three bytes of padding between buff_type and size not to mention additional padding at the end of buffer. Since size is an unsigned int which must be 4 byte aligned, it can only appear at byte boundaries that are multiples of 4. Thus, the reason for the 3 bytes of padding. In this example it would definitely not be wise to use memcmp because of all the padding.

But let's look at the OP's structure:

struct {
 int score;
char name1[20];
} lol[50];

The above example has no padding since score starts at the very beginning of the structure and starts on a byte boundary which is a multiple of four. Also, note that name1 size is a multiple of 4. Thus no padding is needed and using memcmp is perfectly acceptable.

But let us just say that we are stuck with that ugly structure. How could we use memcmp with that structure which contains padding? Well, the MS compiler would use pragma commands. For example,

#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */

As indicated the current alignment is pushed to the stack and we are now using 1 byte boundaries. Thus, eliminating all the packing in that ugly structure. Since padding is now eliminated, we can use memcmp etc. without any issues. BTW, just about every C, C++ has this capability to work on the 1 byte boundary. Also, this is common practice in a lot of network applications where you may have to transmit/receive ugly structures using the various protocols.

Again, IMHO, the author should have provided the background info on compiler architecture, structure optimization. Not to mention that padding should be avoided at all costs. It's a drain on CPU utilization and a waste of memory resources.

So...

Option 1 is understand the alignment attributes of the system, the data type sizes of the system, do any necessary mental math to determine if the structure is organized optimally, understand and remember the compiler's architecture and structure optimization, then finally use nonstandard pragmas for packing structures when there might be a padding issue. Oh, and redo all of that when either the target OS or compiler changes, which makes your code non-portable.

Option 2 is just compare the structure fields directly.

Sorry, but as a fan of the KISS principle, I'll recommend option 2. :D I'm pretty sure the author of that link also didn't want to burden people with unnecessary non-portable concerns and offered a solution that always works.

Edited 4 Years Ago by deceptikon: n/a

The difference between padding and non padding:

Padding:

struct my_buf {
  char buff_type;
  size_t size;
  char buffer[50];
}

Padding footprint is 60 bytes

NonPadding:

struct my_buf {
   size_t size;
  char buff_type;
   char buffer[51];
};

Nonpadding footprint is 56 bytes

Eliminating padding is always in your best interests no matter how you want to compare the structures.

This article has been dead for over six months. Start a new discussion instead.