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
meansa[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()
, usea[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 (seenarg
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
Post a Comment