im trying to do a sort for the array structure records that i have entered...
so far i've tried to use a book to do the coding...but im lost.. can anyone tell me if im on the right track or where im going wrong!!!

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



void filewrite(void);
void fileprint(struct tuple *myDB);
void quicksort(struct tuple *myDB,FILE *fp, int left, int right);
// Idea here is to enter an array of structures
// write them to disk and read them back


// simple structure
struct tuple {
	char artist[50];
	char album[50];
	char label[50];
	char year[4];
	char type[30];
}cd;

/*********************************************************************************************************/	
void filewrite(void) {
	
	// file pointer
	FILE *fp;
	
	// structures
	struct tuple myDB[3];
	struct tuple otherDB[3];
		
	// variable needed
	int i;
	
	i=1;
	fp = fopen("mymusic.txt","wb");
	
	while(i) {	
		
		printf("Enter the artist name: \n");
		scanf("%s",myDB[i].artist);
		printf("Enter the album: \n");
		scanf("%s",myDB[i].album);
		printf("Enter label name: \n");
		scanf("%s",myDB[i].label);
		printf("Enter year: \n");
		scanf("%d",&myDB[i].year);
		printf("Enter the type of music: \n");
		scanf("%s",&myDB[i].type);
		
		fprintf(fp, "%s     %s     %s     %d     %s\n",myDB[i].artist, myDB[i].album, myDB[i].label,myDB[i].year,myDB[i].type);
		printf("\n\n press 1 to continue,0 to stop");
  		scanf("%d",&i);
	}
	// don't forget to close the file
	fclose(fp);
	
	
}
/********************************************************************************************/

void quicksort(struct tuple *myDB,FILE *fp, int left, int right)
{


if((fp=fopen("mymusic.txt", "rb+")) ==NULL) {
	printf("Cannot Open File For Read/Write.\n");
	exit(1);
	}
	
	printf("Sorting disk file.\n");
	quick_disk(fp, cd);
	fclose(fp);
	printf("List Sorted.\n");
	}
	
	/*A QuickSort For File.*/
	
	void quick_disk(FILE *fp, int count)
	{
	qs_disk(fp, 0, count-1);
	}
	
	void qs_disk(FILE *fp, int left, int right)
	{
		int i,j;
		char x[100];
		
		i=left; j=right;
		
	//	strcpy(x, myDB[i].year(fp,(int)(i+j)/2));/*get the middle zip*/
		
	do {
		while(strcmp(myDB[i].year(fp,i),x)<0 && i<right) i++;
		while(strcmp(myDB[i].year(fp,j),x)>0 && j>left) j--;
		
		if(i<=j) {
			swap_all_fields(fp, i, j);
			i++; j--;
			
		}
		
	  } while(i<=j);
	  
	  if(left<j) qs_disk(fp, left, (int) j);
	  if(i<right) qs_disk(fp, (int) i, right);
	  
	 }
	 
	 void swap_all_fields(FILE *fp, int i, int j)
	 {
	 	char a[sizeof(cd)], b[sizeof(cd)];
		
		/*first read in record i and j */
	
	fseek(fp, sizeof(cd)*i, SEEK_SET);
	fread(a, sizeof(cd), 1, fp);
	
	fseek(fp, sizeof(cd)*j, SEEK_SET);
	fread(b, sizeof(cd), 1, fp);
		
	/*then write them back in opposite slots*/
	
	fseek(fp, sizeof(cd)*j, SEEK_SET);
	fwrite(a, sizeof(cd), 1, fp);
	
	fseek(fp, sizeof(cd)*i, SEEK_SET);
	fwrite(b, sizeof(cd), 1, fp);
	
	}
	

//*****************************************************************************************//
int main(void){
		int c;

	while(c!=6)
   		{  
     
     printf("GIVE CHOICE--\n");
     printf("   1 TO CD Information\n");
     printf("   2 TO Print Data On Screen\n");
     printf("   6 TO EXIT\n\n--");
     scanf("%d",&c);
     
     switch(c)
	 {
	 case 1:
		  filewrite();
		  break;
	 case 2:
		  quicksort();
		  break;
	 case 6:
		  break;
	 default:
		  break;
	 }
    }

  }

Also will it be possible for me to add a critical count, analysis purposes to this sorting??

Dani AI

Generated

There are several small but critical problems in the posted code that explain the compile/run trouble and the incorrect sort behavior. High-level: you are mixing text I/O (fprintf/fscanf-style) with binary record swapping, using the same variable for loop-control and array index, reading a year string with "%d", calling uninitialised variables, and defining functions inside other functions (not standard C). was right to flag binary-vs-text I/O; ’s qsort suggestion is a practical and much simpler route for small-to-medium record sets.

Concrete fixes to apply first: make year an int (or a NUL-terminated string with room for 4 digits + '\0'), stop using scanf("%s") without width limits (use fgets or %49s), never use the same i as both index and menu flag, initialize variables before you test them, and remove nested function definitions. Decide whether you want fixed-size binary records or readable text: pick one and be consistent. If you choose binary, write the whole struct with fwrite and later you may safely fseek/fread/fwrite to swap records. If you choose text, read all records into memory, sort them, then overwrite the file.

For analysis (your "critical count"): count comparisons and swaps. The easiest approach when using qsort is to increment a counter inside the comparator each time it runs; for a file-based disk-quicksort increment the counter where you call strcmp and increment a swap counter inside your swap routine. After sorting print both counters for analysis.

Example comparator + counter (assumes year is an int in the struct):

static size_t compare_count = 0;

int cmp_year_then_artist(const void *pa, const void *pb) {
    const struct tuple *a = pa;
    const struct tuple *b = pb;
    compare_count++;
    if (a->year < b->year) return -1;
    if (a->year > b->year) return 1;
    return strcmp(a->artist, b->artist);
}

/* call:
   qsort(records, n_records, sizeof records[0], cmp_year_then_artist);
   printf("Comparisons: %zu\n", compare_count);
*/

Follow those steps and the code will compile, sort predictably, and give you accurate comparison/swap counts for analysis.

Recommended Answers

All 2 Replies

if you want a binary file, when you are reading/writing it wrong. Notice how much easer this is than writing/reading in text mode?

// write a record
fwrite(&myDB[i], 1, sizeof(MyDB[i]), fp);

// read a record
fread(&myDB[i], 1, sizeof(MyDB[i]), fp);

Does your program even compile correctly? It looks like you have functions inside functions, and possibly undeclared variables -- like cd.

Suggestion, use qsort of stdlib.h (I think)...
you only need to write the compare function and specify the struct size.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.