fgdark fgdark - 24 days ago 7
C++ Question

Why am I getting a segmentation fault error?

I am receiving a segmentation fault and am unsure what that means and cant find whats wrong?
Pico is giving this error,
Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
//Struct groups each line in the file
struct gradesRecord
{
int iIndex; // index on the file
int iStudentNUM; // 'Student' field
int iExamGrouped[3]; // 'Exam 1'..'Exam 3' fields
char cStudentAVG; // 'Grade' field
};
void printUnsortedStringFromFile(int amount, struct gradesRecord A[]);
void printSortedStringFromFile(int amount, struct gradesRecord A[]);
//bool binSearchNUM(int amount, int A[amount], int target,);

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 );
//binSearchNUM(int amount, int A[amount], int target, );
return 0;
}

/*
* Function Name: printUnsortedStringFromFile
*
* Input Parameters: takes array A
*
* Description: This fuction prints the original list that was unsorted in grades.csv
*
* Return Value: void
*/
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 j = 0; //storage index
while((fgets(sLine, 80, spData)) != NULL)
{
sscanf(sLine, "%d, %d, %d, %d, %c",
&(A[j].iStudentNUM), &(A[j].iExamGrouped[0]), &(A[j].iExamGrouped[1]), &(A[j].iExamGrouped[2]),
&(A[j].cStudentAVG));

printf("|%7d| %5d| %5d| %5d| %c| \n",
A[j].iStudentNUM, A[j].iExamGrouped[0], A[j].iExamGrouped[1], A[j].iExamGrouped[2],
A[j].cStudentAVG);
j++; // next row
}
printf("+-------+------+------+------+-----+\n");

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

/*
* Function Name: printSortedStringFromFile
*
* Input Parameters: takes int amount, struct gradesRecord A
*
* Description: This function prints the sorted version of the file grades.csv omitting
* the exam values and giving each string a index number
*
* Return Value: void
*/
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.iExamGrouped[0]), &(grRow.iExamGrouped[1]), &(grRow.iExamGrouped[2]),
&(grRow.cStudentAVG));
// keep the line index of that row
grRow.iIndex = iLine;
// target 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 student 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;
int j = 0;
printf("+-----+-------+-----+\n");
printf("|Index|Student|Grade|\n");
printf("+-----+-------+-----+\n");

int index;
while (j < amount - 1)
{
StudentNUM = A[j].iStudentNUM;
StudentAVG = A[j].cStudentAVG;
index = j+1;
printf("| %4d|%7d| %c| \n", index, StudentNUM, StudentAVG);
j++;
}
printf("+-----+-------+-----+\n");
if (fclose(spData) == EOF)
{
fprintf(stderr, "Error closing the file grades.csv. \n");
exit(2);
}

}

Answer

create grades.csv with this input format:

Student,Exam 1,Exam 2,Exam 3,Grade

for example:

1,18,17,14,18
2,15,18,10,16

and output is, witout any Error, but if grades.csv not exist or have a bad information, you get Segmentation fault (core dumped)

There are 3 lines in file grades.csv . 

+-------+------+------+------+-----+
|Student|Exam 1|Exam 2|Exam 3|Grade|
+-------+------+------+------+-----+
|      1|    18|    17|    14|    1| 
|      2|    15|    18|    10|    1| 
+-------+------+------+------+-----+
+-----+-------+-----+
|Index|Student|Grade|
+-----+-------+-----+
|    1|      1|    1| 
|    2|      2|    1| 
+-----+-------+-----+