How can I construct the array problem?

Array string sort problem

  • I cant get my sort array to work ! All it does is print out garbage. The grade.txt file I use is this. The program reads the array/removes the withdrawals just fine. It just wont sort for some reason. 11 5 Gupta Anil 96 90 85 90 80 Jeffers Jose 60 0 70 50 30 Evans Rudy 80 60 70 50 75 Williams Jason 50 40 0 0 70 Ball Adam 90 80 60 55 60 Arnold Joshua 0 0 0 0 0 Scot Michael 80 70 0 0 60 Cook Bret 95 80 80 70 60 Davis Ronald 0 0 0 0 0 Fox Brian 70 60 60 40 50 Hale Frank 60 50 60 30 40 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LENGTH 30 struct students { char firstname[MAX_NAME_LENGTH]; char lastname[MAX_NAME_LENGTH]; int totalgrades[5]; double overall; }; struct students* fread(char fname[], int *numstudents, int *numgrades); struct students* sortarray(int *numstudents); int main() { struct students *cprogramming; int numstudents, numgrades; char fname[20]; // Prompt for the filename printf("Enter the name of the file containing the grades.\n"); scanf("%s",fname); // Read the file in, eliminating the withdrawals cprogramming = fread(fname, &numstudents, &numgrades); puts("The original list of names are:"); for (int i = 0; i < numstudents; i++) puts(cprogramming[i].lastname); puts("The sorted list of names are:"); cprogramming = sortarray(&numstudents); for (i = 0; i < numstudents; i++) puts(cprogramming[i].lastname); return 0; } // Reads the file and removes all the withdrawal students struct students* fread(char fname[], int *numstudents, int *numgrades) { FILE *ifp; struct students *mylist; ifp = fopen(fname, "r"); if(!ifp) { /* check to see if there were errors */ printf("Error: file not found\n"); return 0; } fscanf(ifp, "%d", numstudents); fscanf(ifp, "%d", numgrades); // creates a temp array called mylist that will be used to hold the struct data mylist = (struct students *)malloc((*numstudents)*sizeof(struct students)); //the loop reads in the names and the grades for the class for (int i = 0; i < *numstudents; i++) { int withdrawal = 0; fscanf(ifp, "%s", mylist[i].lastname); fscanf(ifp, "%s", mylist[i].firstname); for (int j = 0; j < *numgrades; j++) { fscanf(ifp, "%d", &(mylist[i].totalgrades[j])); if(mylist[i].totalgrades[j] != 0) withdrawal++; } if(withdrawal == 0) { i--; *numstudents = *numstudents - 1; } } //returns array after withdrawals return mylist; } // Sort the array in alphabetical order struct students* sortarray(int *numstudents) { int r; char temp[30]; struct students *mylist; mylist = (struct students *)malloc((*numstudents)*sizeof(struct students)); for(int a = 0; a < *numstudents; a++) { for(int b= a + 1; b < *numstudents; b++) { r = strcmp(mylist[a].lastname,mylist[b].lastname); if(r > 0) { strcpy(temp,mylist[a].lastname); strcpy(mylist[a].lastname,mylist[b].lastname); strcpy(mylist[b].lastname,temp); } } } return mylist; }

  • Answer:

    Hello Fikal, What you provided is very close to a correct solution. The comment by maximumprophet is basically correct as well. Let me summarize the changes between the version you provided and the one that follows at the end of the answer. [1] Renamed fread to readfile. With gcc, the original name causes an error since your declaration of fread conflicts with the standard version. The following is from the fread(3) man file. Changed the declaration, definition, and call. #include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); [2] Added a second parameter named "mylist" to the sortarray function. This passes the array generated by readfile to sortarray. Changed the declaration, definition, call, and removed mylist definition / malloc call in sortarray. [3] Moved declarations of loop variables. In several places, you used for (int i=0; i < numstudents; i++) [or something similar]. In most cases, use was in the loop but in a single case the code used that variable i after the end of the loop. Depending on your C compiler, this is or is not supported. In gcc, it causes a warning or error, depending on settings of -std=. It is more portable to move the declarations to the scope of the function. Added / removed declarations in several locations. After these changes, the program now does the following: maniac% ./a Enter the name of the file containing the grades. a.txt The original list of names are: Gupta Jeffers Evans Williams Ball Scot Cook Fox Hale The sorted list of names are: Ball Cook Evans Fox Gupta Hale Jeffers Scot Williams which appears to do what you wanted. If you have any further questions related to how the new code works, do not hesitate to make a clarification request. --Maniac Revised code follows [I hope it formats OK in the answer...] [fix long lines as needed when you copy / paste] #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LENGTH 30 struct students { char firstname[MAX_NAME_LENGTH]; char lastname[MAX_NAME_LENGTH]; int totalgrades[5]; double overall; }; struct students* readfile(char fname[], int *numstudents, int *numgrades); struct students* sortarray(int *numstudents, struct students* mylist); int main() { struct students *cprogramming; int numstudents, numgrades; char fname[20]; int i; // Prompt for the filename printf("Enter the name of the file containing the grades.\n"); scanf("%s",fname); // Read the file in, eliminating the withdrawals cprogramming = readfile(fname, &numstudents, &numgrades); puts("The original list of names are:"); for (i = 0; i < numstudents; i++) puts(cprogramming[i].lastname); puts("The sorted list of names are:"); cprogramming = sortarray(&numstudents, cprogramming); for (i = 0; i < numstudents; i++) puts(cprogramming[i].lastname); return 0; } // Reads the file and removes all the withdrawal students struct students* readfile(char fname[], int *numstudents, int *numgrades) { FILE *ifp; struct students *mylist; int i, j; ifp = fopen(fname, "r"); if(!ifp) { /* check to see if there were errors */ printf("Error: file not found\n"); return 0; } fscanf(ifp, "%d", numstudents); fscanf(ifp, "%d", numgrades); // creates a temp array called mylist that will be used to hold the struct data mylist = (struct students *)malloc((*numstudents)*sizeof(struct students)); //the loop reads in the names and the grades for the class for (i = 0; i < *numstudents; i++) { int withdrawal = 0; fscanf(ifp, "%s", mylist[i].lastname); fscanf(ifp, "%s", mylist[i].firstname); for (j = 0; j < *numgrades; j++) { fscanf(ifp, "%d", &(mylist[i].totalgrades[j])); if(mylist[i].totalgrades[j] != 0) withdrawal++; } if(withdrawal == 0) { i--; *numstudents = *numstudents - 1; } } //returns array after withdrawals return mylist; } // Sort the array in alphabetical order struct students* sortarray(int *numstudents, struct students *mylist) { int r; char temp[30]; // struct students *mylist; int a, b; // mylist = (struct students *)malloc((*numstudents)*sizeof(struct students)); for(a = 0; a < *numstudents; a++) { for(b= a + 1; b < *numstudents; b++) { r = strcmp(mylist[a].lastname,mylist[b].lastname); if(r > 0) { strcpy(temp,mylist[a].lastname); strcpy(mylist[a].lastname,mylist[b].lastname); strcpy(mylist[b].lastname,temp); } } } return mylist; }

fikal-ga at Google Answers Visit the source

Was this solution helpful to you?

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.