Reputation: 1896
I am very new to C, but have an assignment for college to complete, so please forgive any stupidity in this question.
I am trying to parse a CSV into structs. When I run the following code, I get no problems in compiling, and it runs fine (albeit only printing out the results, and not assigning them to the structs):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
// Structs
struct Course {
char *course_name[50];
int grade;
};
struct Student {
char* name;
struct Course;
int index;
};
char *dataArr[6] = {"Intro to Programming","Databases","Computer Architecture","Ethics in Computer Science","Advanced Programming","Puzzles and Problem Solving"};
// Expand this section for the initial interactivity
// =============================================================================================
void Import_and_Print()
{
printf("\nPlace for importing files and printing results.\n\n");
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
int in_grade;
int i = 0;
const char s[2] = ",";
char *token;
char *sName;
int j;
//fp = fopen("CTASample.csv", "r");
fp = fopen("Sample2.csv", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
read = getline(&line, &len, fp);
j = 0;
while ((read = getline(&line, &len, fp)) != -1) {
char *csvData = line;
token = strtok(csvData,s);
i = 0;
while (token != NULL) {
if (isalpha(token[0]) != 0) {
strcpy(sName, token);
printf("Student name: %s\n", sName);
}
else {
int in_grade = atoi(token);
//printf("%0.f\n", in_grade);
//printf("\n");
printf("Course: %s\tGrade: %i\n", dataArr[i], in_grade);
//struct Course course = {dataArr[i], in_grade};
//struct Student name = {sName, {dataArr[i], in_grade}};
i++;
}
token = strtok(NULL, s);
fflush(stdin);
}
printf("\n\n");
}
}
However, if I change the last commented line to be uncommented, I get the following error:
Grades.c: In function ‘Import_and_Print’: Grades.c:64:60: warning: initialization of ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion] 64 | struct Student name = {sName, {dataArr[i], in_grade}}; | ^~~~~~~~ Grades.c:64:60: note: (near initialization for ‘name..course_name[1]’)
The csv file looks like this:
Intro to Programming,Databases,Computer Architecture,Ethics in Computer Science,Advanced Programming,Puzzles and Problem Solving
James Jameson,80,70,55,12,50,80
Peter Parker,50,55,50,50,50,50
Mary Janeson,40,40,40,23,40,45
Any suggestions on how I can resolve, so that the values from the csv are inputted into the struct correctly?
Upvotes: 2
Views: 90
Reputation: 215360
If you format the compiler error correctly, this little "ASCII art" ^~~~~~~~
is the "here is your bug" indicator, an arrow often pointing out the exact location of the bug:
struct Student name = {sName, {dataArr[i], in_grade}};
| ^~~~~~~~
Nested initialization with braces in C is tricky, because the language is lax with brace placement. We should always use braces when initializing so called aggregates, meaning container types like arrays and structs.
The {dataArr[i], in_grade}
is supposedly an initializer list for a struct, but the first member of that struct is an array which you didn't surround with braces.
dataArr[i]
initializes the first element in the array correctly since it has the correct type char*
, but then the compiler thinks in_grade
is used for initializing the second item in that array. Hence "initialization of ‘char *’ from ‘int’".
Simply add additional braces:
struct Student name = {sName, { {dataArr[i]}, in_grade}};
Please note however that this initialization list is still strange and sloppy: it only initializes the first item of the course_name
array and it doesn't initialize index
explicitly, so that one gets set to zero implicitly.
The "pro tip" for making the code more readable is designated initializers and proper indention:
struct Student name =
{
.name = sName,
.Course =
{
.course_name = { [0] = dataArr[i] }, // make it explicit that you init index 0 only
.grade = in_grade,
},
.index = something;
};
Upvotes: 3