2016-11-12 1 views
0

Ich habe Probleme beim Sortieren dieser Datei, indem ich jeder Zeile einen Index gebe. Der entscheidende Punkt ist, den Benutzer aufzufordern, den Index einzugeben, damit das Programm die Programmzeile zurückgeben kann, die der Indexnummer entspricht. Hier ist mein Code:Wie Sie Strings aus einer Datei sortieren, indem Sie jeder Zeile einen sortierten Index unter Verwendung der Einfügesortierung geben C

#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; 
    do 
    { 
     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 are %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 the 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 the 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 the file grades.csv.\n"); 
     exit(1); 
    } 
    //help needed implementing insertion sort to sort each string as an index here 
    { 
    int walk; 
    int temp; 
    for (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 to sort these strings into a numbered(index) list 
    } 
    if (fclose(spData) == EOF) 
    { 
     fprintf(stderr, "Error closing the file grades.csv. \n"); 
     exit(2); 
    } 

} 
/* (correct) example output: 
There are 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| 
+-----+-------+-----+ 
*/ 

Antwort

0

Answer Part One.

Das Hauptproblem in Ihrem Quellcode ist die Zeichenfolge char A[amount];.

In der main() Funktion ist die Variable A der Anzahl der Zeilen zugeordnet? !!

In your example, number_of_lines = 5 means A[amount] = A[5] is able to store only a 4-characters string + null terminator.

printf("There are %d lines in file grades.csv . \n", number_of_lines); 
int amount = number_of_lines; 
char A[amount]; 
printUnsortedStringFromFile(amount, A); 
printSortedStringFromFile(amount, A); 

dann auf beiden printUnsortedStringFromFile() und printSortedStringFromFile() Funktionen die gleiche Variable A wird als Puffer verwendet, um eine Linie zu laden und zu lesen.

In your example, the first line of 'grades.csv' is longer 4 characters and is truncated before calling sscanf() .

while((fgets(A, amount, spData)) != NULL) 
{ 
    sscanf(A, "%d, %d, %d, %d, %c", &StudentNUM, &ex1, &ex2, &ex3, &StudentAVG); 

A solution could be to use a local char sTmp[80] for the fgets() and sscanf() and use the A[amount] only for the indexation.


Answer Part Two.

Das zweite Problem im Quellcode ist, dass die vorgeschlagene Indexierung, um durch Insertionsort Schüler-ID sortieren Datensätze aufsteigend, nicht nur speichern, muss die Index aber auch den Inhalt jedes Datensatzes.Ich schlage vor, eine Struktur wie folgt zu verwenden definieren:

struct gradesRecord { 
    int iIndex;  // index on the file 
    int iStudentNUM; // 'Student' field 
    int iExamVAL[3]; // 'Exam 1'..'Exam 3' fields 
    char cStudentAVG; // 'Grade' field 
}; 

Dann von char zu struct gradesRecord (in main()) Ihre A[] Array konvertieren:

int amount = number_of_lines; 
struct gradesRecord A[amount]; 
printUnsortedStringFromFile(amount, A); 
printSortedStringFromFile(amount, A); 

In der printUnsortedStringFromFile() Funktion, das Array A[] wird verwendet, um direkt in die Leseschleife:

To prevent a bad formatted text-file, it is recommended to check the returned value of sscanf() in order to detect missing parameters (see the nArg variable and how to check bellow).

char sLine[81]; // local string to read one 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) { 
     // the input line is not correct !!! 
     // manage that 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 

Dann in der printSortedStringFromFile() Funktion wird das Array A[] zu speichern, zu sortieren in dem Leseschleife, dann angezeigt, in einer zweiten Schleife verwendet:

erste Schleife zu lesen und Auswahl Sortieren aller Zeilen:

char sLine[81]; 
int iLine = 0, iRow; 
struct gradesRecord grRow,grTmp; 

while((fgets(sLine, 80, spData)) != NULL) 
{ 
    // extract one Row and store it into grRow 
    sscanf(sLine, "%d, %d, %d, %d, %c", 
     &(grRow.iStudentNUM), &(grRow.iExamVAL[0]), 
     &(grRow.iExamVAL[1]), &(grRow.iExamVAL[2]), 
     &(grRow.cStudentAVG)); 
    // keep the line index of that row 
    grRow.iIndex = iLine; 
    // search loop = insertion sort algorithm 
    for (iRow=0;iRow<iLine;iRow++) { 
     // detect if new student is before the store one 
     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 the biggest student at the end 
    memcpy(&(A[iLine]),&grRow,sizeof(struct gradesRecord)); 
    iLine++; 
} 

zweite Schleife, zeigen Sie das sortierte Tabelle:

while (z < amount) 
{ 
    StudentNUM = A[z].iStudentNUM; 
    StudentAVG = A[z].cStudentAVG; 
    index = A[z].iIndex; 
    printf("| %4d|%7d| %c| \n", index, StudentNUM, StudentAVG); 
    z++; 
} 
+0

Danke für die Hilfe, meine unsortierten Tabelle nun den Ausdruck in Ordnung, aber ich bin verwirrt darüber, wie die Schüler-IDs in aufsteigender Reihenfolge zu sortieren Verwenden Sie Insertion Sortierung jeweils mit einem entsprechenden Index. – fgdark

+0

Ja, ich weiß, dass meine Antwort nicht die vollständige Lösung Ihrer Frage ist, aber es ist ein erster Schritt, um eine zu finden. Können Sie Ihre Frage so bearbeiten, dass ** die Sortierung der Schüler-IDs in aufsteigender Reihenfolge mit der Einfügesortierung ** erfolgt? –

+0

Hinzufügen des ** "Antwort Teil Zwei." ** mit Indexierung und Einfügesortierung. –

0

um alle Änderungen in der ersten Antwort beschrieben zu synthetisieren, füge ich hier die komplette Quelle als follo w:

1- The function main() and struct gradesRecord :

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 

struct gradesRecord { 
    int iIndex;  // index on the file 
    int iStudentNUM; // 'Student' field 
    int iExamVAL[3]; // 'Exam 1'..'Exam 3' fields 
    char cStudentAVG; // 'Grade' field 
}; 

void printUnsortedStringFromFile(int amount, struct gradesRecord A[]); 
void printSortedStringFromFile(int amount, struct gradesRecord A[]); 

int main() 
{ 

    FILE* spData = fopen("grades.csv", "r"); 
    int ch, number_of_lines = 0; 
    do 
    { 
     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 are %d lines in file grades.csv . \n", number_of_lines); 
    int amount = number_of_lines; 
    struct gradesRecord A[amount]; 
    printUnsortedStringFromFile(amount, A); 
    printSortedStringFromFile(amount, A); 
    return 0; 
} 

2- The function printUnsortedStringFromFile() :

void printUnsortedStringFromFile(int amount, struct gradesRecord A[]) 
{ 
    FILE *spData; 
    spData = fopen("grades.csv", "r"); 
    if(spData == NULL) 
    { 
     fprintf(stderr, "Error opening the file grades.csv.\n"); 
     exit(1); 
    } 

    printf("+-------+------+------+------+-----+\n"); 
    printf("|Student|Exam 1|Exam 2|Exam 3|Grade|\n"); 
    printf("+-------+------+------+------+-----+\n"); 
    char sLine[81]; // local string to read one row 
    int z = 0; 
    while((fgets(sLine, 80, spData)) != NULL) 
    { 
     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)); 

     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++; 
    } 
    printf("+-------+------+------+------+-----+\n"); 

    if (fclose(spData) == EOF) 
    { 
     fprintf(stderr, "Error closing the file grades.csv. \n"); 
     exit(2); 
    } 
} 

3- And the function printSortedStringFromFile() :

void printSortedStringFromFile(int amount, struct gradesRecord A[]) 
{ 
    FILE *spData; 
    spData = fopen("grades.csv", "r"); 
    if(spData == NULL) 
    { 
     fprintf(stderr, "Error opening the file grades.csv.\n"); 
     exit(1); 
    } 

    char sLine[81]; 
    int iLine = 0, iRow; 
    struct gradesRecord grRow,grTmp; 

    while((fgets(sLine, 80, spData)) != NULL) 
    { 
     // extract one Row and store it into grRow 
     sscanf(sLine, "%d, %d, %d, %d, %c", 
      &(grRow.iStudentNUM), &(grRow.iExamVAL[0]), 
      &(grRow.iExamVAL[1]), &(grRow.iExamVAL[2]), 
      &(grRow.cStudentAVG)); 
     // keep the line index of that row 
     grRow.iIndex = iLine; 
     // search loop = insertion sort algorithm 
     for (iRow=0;iRow<iLine;iRow++) { 
      // detect if new student is before the store one 
      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 the biggest student at the end 
     memcpy(&(A[iLine]),&grRow,sizeof(struct gradesRecord)); 
     iLine++; 
    } 

    int StudentNUM; 
    char StudentAVG; 

    printf("+-----+-------+-----+\n"); 
    printf("|Index|Student|Grade|\n"); 
    printf("+-----+-------+-----+\n"); 
    int z = 0; 
    int index; 
    while (z < amount) 
    { 
     StudentNUM = A[z].iStudentNUM; // access to sorted array 
     StudentAVG = A[z].cStudentAVG; 
     index = A[z].iIndex; 
     printf("| %4d|%7d| %c| \n", index, StudentNUM, StudentAVG); 
     z++; 
    } 
    if (fclose(spData) == EOF) 
    { 
     fprintf(stderr, "Error closing the file grades.csv. \n"); 
     exit(2); 
    } 

} 
+0

Vielen Dank. – fgdark

Verwandte Themen