How to sort strings from a file by giving each line an ordered index using insertion sort in C -


i'm having trouble sorting file, giving each line index. whole point prompt user type in index program can return program line corresponds index number. here code:

#include <stdio.h> #include <stdlib.h> #include <stdbool.h>  void printunsortedstringfromfile(int amount, char a[]); void printsortedstringfromfile(int amount, char a[]); //bool binsearchnum(int amount, int a[amount], int target, int *current);  int main() {      file* spdata = fopen("grades.csv", "r");     int ch, number_of_lines = 0;         {         ch = fgetc(spdata);         if (ch == '\n')             number_of_lines++;     } while (ch != eof);      if (ch != '\n' && number_of_lines != 0)         number_of_lines++;      fclose(spdata);      printf("there %d lines in file grades.csv . \n", number_of_lines);     int amount = number_of_lines;     char a[amount];     printunsortedstringfromfile(amount, a);     printsortedstringfromfile(amount, a);     return 0; }   void printunsortedstringfromfile(int amount, char a[]) {     file *spdata;     spdata = fopen("grades.csv", "r");     if(spdata == null)     {         fprintf(stderr, "error opening file grades.csv.\n");         exit(1);     }       int ex1;     int ex2;     int ex3;     int studentnum;     char studentavg;      printf("+-------+------+------+------+-----+\n");     printf("|student|exam 1|exam 2|exam 3|grade|\n");     printf("+-------+------+------+------+-----+\n");     int z = 0;     while((fgets(a, amount, spdata)) != null)     {         sscanf(a, "%d, %d, %d, %d, %c", &studentnum, &ex1, &ex2, &ex3, &studentavg);         printf("| %d|    %d|    %d|    %d|    %c| \n", studentnum, ex1, ex2, ex3, studentavg);         z++; //prints unsorted correctly     }     printf("+-------+------+------+------+-----+\n");      if (fclose(spdata) == eof)     {         fprintf(stderr, "error closing file grades.csv. \n");         exit(2);     } } void printsortedstringfromfile(int amount, char a[]) {     file *spdata;     spdata = fopen("grades.csv", "r");     if(spdata == null)     {         fprintf(stderr, "error opening file grades.csv.\n");         exit(1);     }   //help needed implementing insertion sort sort each string index here     {     int walk;     int temp;     (int cur = 1; cur < amount; cur++)         {         bool located = false;          temp = a[cur], walk = cur-1;         while (walk >= 0 && !located)         {             if (temp < a[walk])                 {                 a[walk+1] = a[walk];                 walk--;                     }                     else                     {                         located = true;                     }         }             a[walk+1] = temp;         }     }       int studentnum;     char studentavg;      printf("+-----+-------+-----+\n");     printf("|index|student|grade|\n");     printf("+-----+-------+-----+\n");     int z = 0;     while((fgets(a, amount, spdata)) != null)     {         sscanf(a, "%d, %c", &studentnum, &studentavg);         printf("|    %d|    %c| \n", studentnum, studentavg);         z++; //student id prints, grade average doesn/t, unsure how sort these strings numbered(index) list     }     if (fclose(spdata) == eof)     {         fprintf(stderr, "error closing file grades.csv. \n");         exit(2);     }  } /* (correct) example output: there 5 lines in file grades.csv. original: +-------+------+------+------+-----+ |student|exam 1|exam 2|exam 3|grade| +-------+------+------+------+-----+ | 535743|    67|    96|    93|    b| | 112213|    87|    65|    72|    c| | 612778|    59|    58|    97|    c| | 151774|    52|   100|    86|    c| | 406704|    54|    72|    80|    d| +-------+------+------+------+-----+ sorted: +-----+-------+-----+ |index|student|grade| +-----+-------+-----+ |    1| 112213|    c| |    2| 151774|    c| |    3| 406704|    d| |    4| 535743|    b| |    5| 612778|    c| +-----+-------+-----+ */ 

answer part one.

the main problem in source code string char a[amount];.

in main() function variable a allocated number of lines ?!!

in example, number_of_lines = 5 means a[amount] = a[5] able store 4-characters string + null terminator.

printf("there %d lines in file grades.csv . \n", number_of_lines); int amount = number_of_lines; char a[amount]; printunsortedstringfromfile(amount, a); printsortedstringfromfile(amount, a); 

then on both printunsortedstringfromfile() , printsortedstringfromfile() functions same variable a used buffer load , read 1 line.

in example, first line of 'grades.csv' longer 4 characters , truncated before calling sscanf().

while((fgets(a, amount, spdata)) != null) {     sscanf(a, "%d, %d, %d, %d, %c", &studentnum, &ex1, &ex2, &ex3, &studentavg); 

a solution use local char stmp[80] fgets() , sscanf() , use a[amount] indexation.


answer part two.

the second problem in source code suggested indexation in order ascending student-id sort records insertion sort, needs store not index content of each record. suggest use define structure follow:

struct gradesrecord {     int iindex;       // index on file     int istudentnum;  // 'student' field     int iexamval[3];  // 'exam 1'..'exam 3' fields     char cstudentavg; // 'grade' field }; 

then convert a[] array char struct gradesrecord(in main()):

int amount = number_of_lines; struct gradesrecord a[amount]; printunsortedstringfromfile(amount, a); printsortedstringfromfile(amount, a); 

in printunsortedstringfromfile() function, array a[] used directly in reading loop:

to prevent bad formatted text-file, recommended check returned value of sscanf() in order detect missing parameters (see narg variable , how check bellow).

char sline[81]; // local string read 1 row int z = 0; // storage index int narg;  while((fgets(sline, 80, spdata)) != null) {     narg = sscanf(sline, "%d, %d, %d, %d, %c",         &(a[z].istudentnum), &(a[z].iexamval[0]),         &(a[z].iexamval[1]), &(a[z].iexamval[2]),         &(a[z].cstudentavg));      if (narg != 5) {         // input line not correct !!!         // manage error.     }      printf("|%7d| %5d| %5d| %5d|    %c| \n", a[z].istudentnum,         a[z].iexamval[0], a[z].iexamval[1], a[z].iexamval[2],         a[z].cstudentavg);     z++; // next row 

then in printsortedstringfromfile() function, array a[] used store, sort in reading loop, displayed in second loop:

first loop, reading , selection sort of rows:

char sline[81]; int iline = 0, irow; struct gradesrecord grrow,grtmp;  while((fgets(sline, 80, spdata)) != null) {     // extract 1 row , store grrow     sscanf(sline, "%d, %d, %d, %d, %c",         &(grrow.istudentnum), &(grrow.iexamval[0]),         &(grrow.iexamval[1]), &(grrow.iexamval[2]),         &(grrow.cstudentavg));     // keep line index of row     grrow.iindex = iline;     // search loop = insertion sort algorithm     (irow=0;irow<iline;irow++) {         //  detect if new student before store 1         if (grrow.istudentnum < a[irow].istudentnum) {             // exchange both stuident records through grtmp             memcpy(&grtmp,&(a[irow]),sizeof(struct gradesrecord));             memcpy(&(a[irow]),&grrow,sizeof(struct gradesrecord));             memcpy(&grrow,&grtmp,sizeof(struct gradesrecord));         }     }     // store biggest student @ end     memcpy(&(a[iline]),&grrow,sizeof(struct gradesrecord));     iline++; } 

second loop, display sorted table:

while (z < amount) {     studentnum = a[z].istudentnum;     studentavg = a[z].cstudentavg;     index = a[z].iindex;     printf("| %4d|%7d|    %c| \n", index, studentnum, studentavg);     z++; } 

Comments

Popular posts from this blog

php - How to display all orders for a single product showing the most recent first? Woocommerce -

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

angularjs - How restrict admin panel using in backend laravel and admin panel on angular? -