I'm trying to assign values from an array containing all strings to an array of structs, where some of the struct members are integers. The way I've attempted it causes some undefined behavior, though. Like the code below generates the following:
0 surname ▒▒
1 forename &
2 id 0
when it should say
0 surname Boatswain
1 forename Michael Jr
2 id 109993267
I'm not exactly sure what's wrong with the way I've assigned these values though.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//There are 7 values for each student
#define VALUES 7
struct Students{
int term;
int id; // NEED TO GENERATE ERROR IF WRONG NUM OF CHARACTERS
char surname[15];
char forename[15];
char subject[3];
int catnum;
char section[3];
};
int main(int argc, char *argv[]){
//Get contents of input file
unsigned char filename;
printf("Enter the input file name: \n");
scanf("%s", &filename);
FILE *file = fopen(&filename, "r");
int filesize=0;
fseek(file, 0L, SEEK_END);
filesize = ftell(file);
fseek(file, 0L, SEEK_SET);
char *contents = malloc(filesize+1);
size_t size=fread(contents,1,filesize,file);
contents[size]=0; // what does all this do exactly?
//Get number of lines in input file
int total_line = 0;
const char *str;
for(str = contents; *str; ++str)
total_line += *str == '\n';
//Tokenize string
int n=0,nn;
char *b[VALUES*total_line];
char *ds=strdup(contents);
b[n]=strtok(ds, ",=\"\r\n\"");
while(b[n] && n<((VALUES*total_line)-1)) b[++n]=strtok(NULL, ",=\"\r\n\"");
//for(nn=0; nn<=n; ++nn) printf("%s %d ", b[nn], nn);
//putchar('\n');
free(ds);
struct Students record[total_line];
int i, j;
for(i=0;i++;i<total_line){
for(j=0;j++;j<VALUES){
int n=(7*i)+j;
record[i].term=atoi(b[n]);
record[i].id=atoi(b[n]);
strcpy(record[i].surname, b[n]);
strcpy(record[i].forename, b[n]);
strcpy(record[i].subject, b[n]);
record[i].catnum=atoi(b[n]);
strcpy(record[i].section, b[n]);
}
}
// try printing some values here
printf("0 surname %s\n",record[0].surname);
printf("1 forename %s\n",record[1].forename);
printf("2 id %d\n", record[2].id);
free(contents);
return 0;
}
Input file:
1301,107515018,"Boatswain","Michael R.",CSE, 230,="R01"
1301,109993269,"Castille","Michael Jr",CSE, 230,="R03"
1301,109993267,"Castille","Janice",CSE, 230,="R03"
Thank you in advance for the help!
Edit: What is the issue in changing the for loop like so?
for(i=0;i<total_line;i++) {
record[i].term=atoi(b[(7*i)]);
record[i].id=atoi(b[(7*i)+1]);
strcpy(record[i].surname, b[(7*i)+2]);
strcpy(record[i].forename, b[(7*i)+3]);
strcpy(record[i].subject, b[(7*i)+4]);
record[i].catnum=atoi(b[(7*i)+5]);
strcpy(record[i].section, b[(7*i)+6]);
}
Edit: I got it to work. Just needed to change the for-loop to a while-loop. Edit2: ohh I had the i++ and i total_line switched. derp. fixed now. Well I guess that solves this mystery.
unsigned char filename;means one character. You then writescanf("%s", &filename);which reads many characters . This causes a buffer overflow with unpredictable consequences.