I know I am two days late since this question was asked and a few people have already commented what the solution is. Here is just an answer and summary should anyone need it.
So I copied your code over to check with a debugger. I created a dummy file with the same column headers to test with.
Problem
This was identified by Weather Vane. You are trying to point to an index within the array that is not there. I noticed that on the line's where you assign the token variable to the column value. You set the parameter called *restrict __s to null.
token = strtok(NULL, ",");
Solution
When it should be pointing at the line variable, Like this.
token = strtok(line, ",");
So in short the code was reading a from a Null value and you were trying to assign these null values into an array while converting them. So the conversion would fail for Null values and Null values would end up getting assigned to the array.
This resolved the problem. I got it to print the values in the dummy file and print out the final message.
Here is the how the code should look for what you want to do.
The Code
//The Header library files that the developer was using.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//* So this is a structure that the developer needs to use for his application.
typedef struct
{
int StudentID; // The Student's ID.
float ProvaIngresso; // TryIncome? Sorry I am using google translate.
float NotaSecundario; // Secondary Note.
float NotaCandidatura; // NoteCandidacy.
int Escolha1, Escolha2, Escolha3, Escolha4, Escolha5; // Pick1, Pick2, Pick3, Pick4, Pick5.
char curso1[4], curso2[4], curso3[4], curso4[4], curso5[4]; // Cursor1, Cursor2, Cursor3, Cursor4, Cursor5.
} Candidato;
//* Here he declares a function with no body.
void ColocaCandidatos(Candidato candidatos[]);
//* The main entry point of the application.
int main()
{
Candidato candidatos[100]; // Here the struct object gets declared. 60000 seems a bit excessive?
ColocaCandidatos(candidatos); // Here the method is called.
int x = 1;
int y = 2;
int z = x + y;
printf("%d", z); // I think this is a basic way of checking if the code ran to the end.
return 0; // The application ends here.
}
//* This is the method that reads the file.
void ColocaCandidatos(Candidato candidatos[])
{
// This is where the file handling is done.
FILE *fp; // The FILE variable is declared.
char line[100]; // An array with 101 available entries.
char *token; // A token. The asterisk indicates it will be for a memory cursor variable.
int line_count = 0; // How the user keeps track of what line he is on.
int i = 0; // token pa controlar numero do candidato; // Translation: token to control candidate number
// Open the CSV file for reading.
fp = fopen("Candidatos_N10_C20_O05.csv", "r");
//If the FP variable is null, Then print an error saying the file could not be opened.
if (fp == NULL)
{
printf("Error: could not open file\n"); // This prints the message.
exit(1); // This exits with code 1, Meaning it will report it as an run with error's in the system logs.
}
// Read the lines of the file and extract the string as long as there is data in the file.
while (fgets(line, 100, fp) != NULL)
{
if (line_count > 0) // Skip the first line
{
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].StudentID = atoi(token); // This converts a string to an Integer and assigns it to Student ID variable of the Candidato structure.
printf("\n%d", candidatos[i].StudentID); // This prints the Student's ID, Take note that its getting the value from the structure object. So it's a way of checking the output.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].ProvaIngresso = atof(token); // This converts a string to a float number and assign's it to the TryIncome variable.
printf("\n%f", candidatos[i].ProvaIngresso); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].NotaSecundario = atof(token); // This converts a string to a float number and assign's it to the SecondaryNote variable.
printf("\n%f", candidatos[i].NotaSecundario); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].NotaCandidatura = atof(token); // This converts a string to a float number and assign's it to the NoteCandidacy variable.
printf("\n%f", candidatos[i].NotaCandidatura); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].Escolha1 = atoi(token); // This converts a string to a int number and assign's it to the Pick1 variable.
printf("\n%d", candidatos[i].Escolha1); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
strcpy(candidatos[i].curso1, token); // This copies the value and assign's it to the cursor1 variable.
printf("\n%s", candidatos[i].curso1); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].Escolha2 = atoi(token); // This converts a string to a int number and assign's it to the Pick2 variable.
printf("\n%d", candidatos[i].Escolha2); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
strcpy(candidatos[i].curso2, token); // This converts a string to a float number and assign's it to the cursor2 variable.
printf("\n%s", candidatos[i].curso2); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].Escolha3 = atoi(token); // This converts a string to a float number and assign's it to the Pick3 variable.
printf("\n%d", candidatos[i].Escolha3); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
strcpy(candidatos[i].curso3, token); // This converts a string to a float number and assign's it to the cursor3 variable.
printf("\n%s", candidatos[i].curso3); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].Escolha4 = atoi(token); // This converts a string to a float number and assign's it to the pick4 variable.
printf("\n%d", candidatos[i].Escolha4); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
strcpy(candidatos[i].curso4, token); // This converts a string to a float number and assign's it to the cursor4 variable.
printf("\n%s", candidatos[i].curso4); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
candidatos[i].Escolha5 = atoi(token); // This converts a string to a float number and assign's it to the Pick5 variable.
printf("\n%d", candidatos[i].Escolha5); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
token = strtok(line, ","); // This apparently divides strings into tokens seperated by character's.
strcpy(candidatos[i].curso5, token); // This converts a string to a float number and assign's it to the cursor5 variable.
printf("\n%s", candidatos[i].curso5); // This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.
i++; // Increment the loop integer.
}
line_count++; // Increment the line count.
}
fp = fclose(fp); // Close the reader, It's good practice ;).
}
Addional changes I made to the code and note's
1.I changed the parameter for ColocaCandidatos to use a normal object array.
2.I close the reader at the end of the function, Usually the file will be closed when the function ends but it's a good practice.
3.Declaring the Object Candidato with an array size of 60000 seems a bit excessive, It will be assigning atleast 3,3Mb of memory for the array every time it runs.
4.If I had more time I would have tried implementing a better way of assigning the values for the Candidato object rather than calling the same 3 line's multiple time's but to be fair not all the lines were the same. I would also add something that checks for null type value's before trying to assign the value to a variable.