I am writing a program that reads from a file that contains a list of appointments and then put them into an dynamic array named day. I am having trouble figuring out what is exactly wrong with my program. It keeps on crashing before it finishes reading the file. I figured out that I could add the first day into my array, but I cannot add anymore than that. My guess would be that I did not allocate memory correctly, but I don't see anything wrong with it.

Here are my the functions and structures:

typedef struct {
	int hour;
	int minute;
} Time;

typedef struct {
	Time startTime;
	Time endTime;
	char subject[20];
	char location[20];
} Appointment;

typedef struct {
	int day;
	int month;
	Appointment *appts[8];
	int apptCount;
} Day;

int needMemory(int *daysize, int *allocate){
	if (*daysize == *allocate) { //does day need more memory?
		if (*allocate == 0) // if array is empty
			*allocate = 30; // set initial size of array
		else
			*allocate *= 2; // else size is double
		return TRUE;
	}// if array needs more memory*/
	return FALSE;
} //needMemory() does array need more memory

void addNewDay(Day **array, int daysize, int month, int day){
	int sTh, eTh;
	char AMPM[MAXSIZE];
	
	array[daysize]->day = day; 
	array[daysize]->month = month; 	
	strtok(NULL,"/,:\n");
	array[daysize]->appts[0] = (Appointment *) malloc(sizeof(Appointment));
	strcpy(array[daysize]->appts[0]->subject, strtok(NULL,"/,:\n"));
	sTh = atoi(strtok(NULL,"/,:\n"));
	array[daysize]->appts[0]->startTime.minute = atoi(strtok(NULL,"/,:\n"));
	strcpy(AMPM, strtok(NULL,"/,:\n"));
	array[daysize]->appts[0]->startTime.hour = changeMilitaryTime(sTh, AMPM);
	eTh = atoi(strtok(NULL,"/,:\n"));
	array[daysize]->appts[0]->endTime.minute = atoi(strtok(NULL,"/,:\n"));
	strcpy(AMPM, strtok(NULL,"/,:\n"));
	array[daysize]->appts[0]->endTime.hour = changeMilitaryTime(eTh, AMPM);
	strcpy(array[daysize]->appts[0]->location, strtok(NULL, "/,:\n"));
	array[daysize]->apptCount = 1;
} //addNewDay() adds appointment to a new day
	
void readFile(Day **array, int *daysize, int *allocate, FILE *inp){
	char s[MAXSTRING];
	int tempsize = *daysize, tempallo = *allocate, month, day, dayindex, i;
	fgets(s,100, inp);
	while ((fgets(s,80, inp)) != NULL){ //while not end of file
	//for (i = 0; i<=1; ++i){
		fgets(s,100, inp);
		if ((needMemory(daysize, &tempallo)) == TRUE) 
			*array = (Day *) realloc(*array, tempallo * (sizeof(Day)));
		month = atoi(strtok(s,"/,:\n"));
		day = atoi(strtok(NULL,"/,:\n")); 
		dayindex = findApptDay(array, tempsize, month, day);
		if (dayindex == -1) {//if day not found
			addNewDay(array, tempsize, month, day); //add appointment to a new day
			tempsize += 1;
			//printf("%d",tempsize);
			//printf("%s\n", "DEBUG");
		} else {
			 //printf("%s", "DEBUG");
			 //printf("%d", dayindex);
			 addToday(array, tempsize, month, day, dayindex);
			 tempsize += 1;
			// printf("%s", "DEBUG");
		} 
	}//while not end of file
	*daysize = tempsize;
	*allocate = tempallo;
}// readFile()

int main(){
	FILE *inp;
	Day *day = NULL;
	int choice, daysize = 0, allocate = 0, i;
	
	inp = fopen("appts.csv","r");
	readFile(&day, &daysize, &allocate, inp);
        fclose(inp);
	return 0;
}

There can only be one unique day in the array day and for each day, there can only be 8 appointments. The addToday function adds an appointment and it looks similar to the addNewday function so I didn't include it. Can anyone find out why I cannot add more than one day?

What's the purpose of using three consecutive fgets? (line 55, 56 and 58)
Buffer s always contains the contents read by third fgets so can you tell how data is organised in your file.

I was doing some debugging to try to find out what exactly is going on with the function. There was supposed to be on two consecutive fgets. The first one reads in the first line of the file that shows what each column is so I didn't need it. I must have forgotten to comment out the 3rd fgets since it was for the for statement that I commented out. The for statement was to test how many times is the function loops before it crashes.

void readFile(Day **array, int *daysize, int *allocate, FILE *inp){
	char s[MAXSTRING];
	int tempsize = *daysize, tempallo = *allocate, month, day, dayindex, i;
	fgets(s,100, inp);
	while ((fgets(s,80, inp)) != NULL){ //while not end of file
	//for (i = 0; i<=1; ++i){
		//fgets(s,100, inp);
		if ((needMemory(daysize, &tempallo)) == TRUE) 
			*array = (Day *) realloc(*array, tempallo * (sizeof(Day)));
		month = atoi(strtok(s,"/,:\n"));
		day = atoi(strtok(NULL,"/,:\n")); 
		dayindex = findApptDay(array, tempsize, month, day);
		if (dayindex == -1) {//if day not found
			addNewDay(array, tempsize, month, day); //add appointment to a new day
			tempsize += 1;
			//printf("%d",tempsize);
			//printf("%s\n", "DEBUG");
		} else {
			 //printf("%s", "DEBUG");
			 //printf("%d", dayindex);
			 addToday(array, tempsize, month, day, dayindex);
			 tempsize += 1;
			// printf("%s", "DEBUG");
		} 
	}//while not end of file
	*daysize = tempsize;
	*allocate = tempallo;
}// readFile()

Please let me know if there are any problems with my fgets. I commented out the part that i used to debug the function.

Here is the change military time function so you guys can try to run my program and see what is wrong.

int changeMilitaryTime(int hour, char AMPM[]) {
	char PM[MAXSIZE] = "00 PM", AM[MAXSIZE] = "00 AM";
	if ((AMPM == PM) && (hour != 12))
		hour += 12;
	else if ((AMPM == AM) && (hour == 12))
		hour += 12;
	return hour;
} //changeMilitaryTime
strcpy(array[daysize]->appts[0]->subject, strtok(NULL,"/,:\n"));

avoid something like that. It might give segentation fault if there is no more tokens (strtok() returns NULL).

Make a check before doing any operation on the string pointed to by the address returned by the strtok() function.

char *c = strtok(NULL, "/,:\n");
if(c!=NULL)
       /*proceed*/

Hm...., that might actually be the problem. When I try to print out all of my data in day[0], I got no error and it did print them out correctly. But when I try to print out data in day[1], I got no error for printing out day and month, but as soon as I try to print out the remaining data, my program crashes. The weird thing was that the program printed out 0 for my day and month in day[1]. I am going to need some help fix this =/

In the lines:

fgets(s,100, inp);
		if ((needMemory(daysize, &tempallo)) == TRUE) {
			*array = (Day *) realloc(*array, tempallo * (sizeof(Day)));}
		month = atoi(strtok(s,"/,:\n"));
		day = atoi(strtok(NULL,"/,:\n")); 
		dayindex = findApptDay(array, tempsize, month, day);
		if (dayindex == -1) {//if day not found
			addNewDay(array, tempsize, month, day); //add appointment to a new day

What I was trying to do was get a line from a file and then use strtok() to get the month and day out of the line. Then I would use them to find if there is already a day and month inside my array. My array can only have one unique date (ie no more than one 7/14) and each date have at most 8 appointments. If a date was not already in the array, I will create the date. What probably went wrong was probably my logic on how strtok() actually works. I thought that if I use strtok(s, "/,:\n"), then if I call another function and within that function, if it uses strtok(NULL, "/,:\n"), then it will still use the same line (s) in the previous function. This works for my first data that I might in day[0], but for my second data in day[1], it does not. Can someone find out where did I mess up? When I try to print out day[1].month, it printed out 0, which it should not. I don't even know where the program get 0 in my file. Also note that for some reason when I print out day[1].apptCount, it also printed out a 0 even though after going through the addNewDay() function, it should be 1. day[0] was fine. Please advise

month = atoi(strtok(s,"/,:\n"));
day = atoi(strtok(NULL,"/,:\n"));

u ingnored what i told u in my previous post in these lines.
If strtok() returns NULL u will have atoi(NULL)

I solved it. The problem wasn't the strtok() since I knew the exact format of the file, so theoretically, atoi(NULL) should not happen anyway. The problem arise as I pass my array into a function and then within that function pass that same array to another function. For some reason, it did not return the whole array to my main function. It only returned day[0] back to my main function.

I decided to create some global variables so I didn't need to bother with passing my array to different functions.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.