Hi,
I'm trying to tokenize a string that has been read from a file but I keep getting an assertion failure :
Expression: string != nullptr
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
Here is the code from the function that I'm having an issue with. The assertion failure occurs inside the while() loop - Also, the program isn't close to being finished but this is preventing me from moving forward
Code:
.
void SetProfile(char**ReadData, Profile *User, DayStats *Node, int DaysOnDiet)
{
char *Container;
int k = 1;
User->Name = strtok(ReadData[0], ", ");
Container = strtok(NULL, ",");
User->Height = atoi(Container);
Container = strtok(NULL, ",");
User->StartingWeight = atof(Container);
Container = strtok(NULL, ",");
User->DesiredWeightLoss = atof(Container);
Container = strtok(NULL,",");
User->DesiredDays = atoi(Container);
Container = strtok(NULL, ",");
User->Age = atoi(Container);
Container = strtok(NULL, ",");
User->StartingBMR = atof(Container);
Container = strtok(NULL, ",");
User->Day = atoi(Container);
if (DaysOnDiet > 1)
{
while (ReadData[k] != NULL)
{
Container = strtok(ReadData[k], ",");
Node->Steps = atoi(Container);
Container = strtok(NULL, ",");
Node->BMR = atof(Container);
Container = strtok(NULL, ",");
Node->Weight = atof(Container);
Container = strtok(NULL, ",");
Node->TotalCaloriesBurned = atof(Container);
Container = strtok(NULL, ",");
Node->CaloriesBurnedFromWorkout = atof(Container);
Container = strtok(NULL, ",");
Node->CaloriesConsumed = atof(Container);
Container = strtok(NULL, ",");
Node->CaloricDeficit = atof(Container);
Container = strtok(NULL, ",");
Node->Day = atoi(Container);
k++;
}
}
}
.
The entire code -
Main:
Code:
.
#include "header.h"
int main(void)
{
FILE *infile = fopen("profile.txt", "r");
int DataInFile = FALSE, FileSize = 0, MenuOption = 0, DaysOnDiet, CheckMenu[3] = { 0 }, k = 0, SaveNode = FALSE;
char *ProfileData[365] = {NULL};
Profile *UserProfile = (Profile*)malloc(sizeof(Profile));
DayStats *Node = (DayStats*)malloc(sizeof(DayStats));
Node->Next = NULL;
Head = NULL;
Tail = NULL;
if (infile == NULL)
{
perror("\nAn error occurred while opening the file\n\n");
exit(1);
}
else
{ /*fscanf returns a negative value if there is no data in the file.If profile/file is empty, get user input for starting body parameters, if else - display main menu*/
char *ReadFirstLineOfProfile[100];
double CheckIfProfileIsEmpty = fscanf(infile, "%s", ReadFirstLineOfProfile);
if (CheckIfProfileIsEmpty < 0)
{
GetProfileInfo(UserProfile);
ProfileToFile(UserProfile);
fclose(infile);
}
do {
DaysOnDiet = ReadProfileData(ProfileData, infile);
SetProfile(ProfileData, UserProfile, Node, DaysOnDiet);
MenuOption = MainMenu();//Returns an integer value from user input(menu option)
DayNode(ProfileData, DaysOnDiet, UserProfile, MenuOption, SaveNode,Node);
switch (MenuOption)
{
case 1:CheckMenu[0] = 1;
break;
case 2:CheckMenu[1] = 1;
break;
case 3:CheckMenu[2] = 1;
break;
}
for (int i = 0; i < 3; i++)
{
if (CheckMenu[i] == 1)
SaveNode = TRUE;
}
if (MenuOption == 6)
{
DayStats *temp = (DayStats*)malloc(sizeof(DayStats));
if (Tail == NULL)
{
Tail = Head = Node;
Tail->Next = Head;
Head->Next = NULL;
}
else
{
temp->Next = Tail;
Tail = temp;
}
free(temp);
AppendFromTail(Tail);
SaveNode = FALSE;
for (int i = 0; i < 3; i++)
CheckMenu[i] = 0;
}
} while (MenuOption != 7);
}
return 0;
}
.
definitions:
Code:
.
void GetProfileInfo(Profile *User)
{
int MALE = 1, FEMALE = 2;
printf("\n\n\t\t\t\tWeight Loss Tracker...\n");
/****************REMEMBER TO ADD SLEEP FUNCTION HERE!!*/
CLEAR;
printf("\n\n\t\t\tFirst, I will need some information from you so that I can generate your profile...\n");
CLEAR;
User->Name = (char*)malloc(100);
/*Enter User Name and measurables*/
printf("\n\nEnter your name:");
scanf("%[^\n]%*c", User->Name);
CLEAR;
printf("\n%s, enter your Height(inches):", User->Name);
scanf("%d", &User->Height);
CLEAR;
printf("\nEnter your weight(pounds):");
scanf("%lf", &User->StartingWeight);
CLEAR;
printf("\nEnter your age:");
scanf("%d", &User->Age);
CLEAR;
printf("\nHow much weight(pounds) do you want to lose?:");
scanf("%lf", &User->DesiredWeightLoss);
CLEAR;
printf("\In how many days do you want to meat your goal?:");
scanf("%d", &User->DesiredDays);
CLEAR;
printf("\nWhich gender are you?\n1.Male\n2.Female\n");
int Gender;
scanf("%d", &Gender);
if (Gender == MALE)
User->StartingBMR = (66.47) + (13.7 * (User->StartingWeight)) + (5 * (User->Height * 2.54)) - (6.8 * (User->Age));
else if(Gender == FEMALE)
User->StartingBMR = (655.1) + (9.6 * (User->StartingWeight)) + (1.8 * (User->Height * 2.54)) - (4.7 * (User->Age));
CLEAR;
return;
}
void ProfileToFile(Profile *user)
{
/*Pre condition: the profile.txt file is empty*/
/*Post condition: profile.txt is opened for writing.The first line of the profile.txt file contains data pertaining to the initial body parameters. Commas are used as data delimeters.
Profile.txt is closed for writing at the conclusion of this function*/
FILE *outfile = fopen("profile.txt", "w");
fprintf(outfile,"%s,%d,%.2lf,%.2lf,%d,%d,%.2lf,1\n", user->Name, user->Height, user->StartingWeight, user->DesiredWeightLoss, user->DesiredDays, user->Age, user->StartingBMR);
fclose(outfile);
}
int MainMenu()
{
int MenuOption;
printf("\n\t\t\t\t Weight Manager\n");
printf("\n1.Log Workout\n2.Log Steps\n3.Log Calories\n4.View Stats\n5.Edit Profile\n6.Next Day\n7.Exit\n");
scanf("%d", &MenuOption);
return MenuOption;
}
int ReadProfileData(char **ProfileData, FILE *infile)
{
/*Pre condition: infile contains data that is not being used by the program*/
/*Post Condition: All data contained in profile.txt is stored in the string array 'ProfileData' -
where each ProfileData[index] contains a string of characters that are grouped by the line position
of the profile.txt file*/
int k = 0;
infile = fopen("profile.txt", "r");
if (infile == NULL)//if profile is empty print an error message
{
perror("\nProfile Data Does Not exist\n");
exit(1);
}
else
{ /*Reserve 200 bytes of character data in memory for ProfileData[k]*/
ProfileData[k] = (char*)malloc(200);
/*Read contiguous lines from infile and store
the data as strings in the string array 'ProfileData' until the end of file is reached. The first
200 characters will be read into the array*/
while (fgets(ProfileData[k], 200, infile) != NULL)
{
k++;
ProfileData[k] = (char*)malloc(200);
}
}
fclose(infile);
return k;//Returning this value gives us the number of days the diet has been active.The number of days is equal to the number of lines in the profile.txt file
}
void DayNode(char **ProfileData, int DayOfDiet, Profile *Pro, int MenuOption, int SaveNode, DayStats *Node)
{
int IntData;
double DoubData;
/*Set all struct variables to 0.This is done in case the user chooses to not insert a value for the below(3) Node variables*/
if (SaveNode == 0)
{
Node->Steps = 0;
Node->CaloriesConsumed = 0;
Node->CaloriesBurnedFromWorkout = 0;
}
Node->Day = DayOfDiet;
if (MenuOption == 2)
{
CLEAR;
printf("\n\nEnter the number of steps taken today:");
scanf("%d", &IntData);
Node->Steps += IntData;
CLEAR;
}
if (MenuOption == 3)
{
CLEAR;
printf("\n\nEnter the amount of calories consumed today:");
scanf("%lf", &DoubData);
Node->CaloriesConsumed += DoubData;
CLEAR;
}
if (MenuOption == 1)
{
CLEAR;
printf("\n\nEnter the amount of calories burned from working out:");
scanf("%lf", &DoubData);
Node->CaloriesBurnedFromWorkout += DoubData;
CLEAR;
}
if (DayOfDiet == 1)
{
double CalsPerStep = (0.57 * Pro->StartingWeight)/2200;
double TotalStepCals = Node->Steps * CalsPerStep;
Node->Weight = Pro->StartingWeight - ((Pro->StartingBMR - Node->CaloriesConsumed + Node->CaloriesBurnedFromWorkout + TotalStepCals)/3500);
Node->BMR = (66.47) + (13.7 * (Node->Weight)) + (5 * (Pro->Height * 2.54)) - (6.8 * (Pro->Age));
Node->TotalCaloriesBurned = Pro->StartingBMR + Node->CaloriesBurnedFromWorkout + TotalStepCals;
}
else if (DayOfDiet > 1)
{
double CalsPerStep = (0.57 * Tail->Weight);
double TotalStepCals = Node->Steps * CalsPerStep;
Node->Weight = Tail->Weight - ((Tail->BMR - Node->CaloriesConsumed + Node->CaloriesBurnedFromWorkout + TotalStepCals) / 3500);
Node->BMR = (66.47) + (13.7 * (Node->Weight)) + (5 * (Pro->Height * 2.54)) - (6.8 * (Pro->Age));
Node->TotalCaloriesBurned = Tail->BMR + Node->CaloriesBurnedFromWorkout + TotalStepCals;
}
Node->CaloricDeficit = Node->TotalCaloriesBurned - Node->CaloriesConsumed;
return;
}
void SetProfile(char**ReadData, Profile *User, DayStats *Node, int DaysOnDiet)
{
char *Container;
int k = 1;
User->Name = strtok(ReadData[0], ", ");
Container = strtok(NULL, ",");
User->Height = atoi(Container);
Container = strtok(NULL, ",");
User->StartingWeight = atof(Container);
Container = strtok(NULL, ",");
User->DesiredWeightLoss = atof(Container);
Container = strtok(NULL,",");
User->DesiredDays = atoi(Container);
Container = strtok(NULL, ",");
User->Age = atoi(Container);
Container = strtok(NULL, ",");
User->StartingBMR = atof(Container);
Container = strtok(NULL, ",");
User->Day = atoi(Container);
if (DaysOnDiet > 1)
{
while (ReadData[k] != NULL)
{
Container = strtok(ReadData[k], ",");
Node->Steps = atoi(Container);
Container = strtok(NULL, ",");
Node->BMR = atof(Container);
Container = strtok(NULL, ",");
Node->Weight = atof(Container);
Container = strtok(NULL, ",");
Node->TotalCaloriesBurned = atof(Container);
Container = strtok(NULL, ",");
Node->CaloriesBurnedFromWorkout = atof(Container);
Container = strtok(NULL, ",");
Node->CaloriesConsumed = atof(Container);
Container = strtok(NULL, ",");
Node->CaloricDeficit = atof(Container);
Container = strtok(NULL, ",");
Node->Day = atoi(Container);
k++;
}
}
}
void AppendFromTail(DayStats *Tail)
{
FILE *infile = fopen("profile.txt", "a+");
fprintf(infile, "%d,%.2lf,%.2lf,%.2lf,%.2lf,%.2lf,%.2lf,%d\n", Tail->Steps, Tail->BMR, Tail->Weight, Tail->TotalCaloriesBurned, Tail->CaloriesBurnedFromWorkout, Tail->CaloriesConsumed, Tail->CaloricDeficit,Tail->Day);
fclose(infile);
}
.
Header file:
Code:
.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define CLEAR system("cls");
typedef enum
{
FALSE, TRUE
};
typedef struct profile
{
char *Name;
double StartingWeight;
double CurrentWeight;
double DesiredWeightLoss;
double StartingBMR;
int Height;
int DesiredDays;
int Age;
int Day;
}Profile;
typedef struct daystats
{ /*Weight is calculated in pounds. Height is calculated in inches*/
int Day;
int Steps;
double BMR;
double Weight;
double TotalCaloriesBurned;
double CaloriesBurnedFromWorkout;
double CaloriesConsumed;
double CaloricDeficit;
struct daystats *Next;
}DayStats;
DayStats *Head, *Tail;
void GetProfileInfo(Profile *User);
void ProfileToFile(Profile *user);
int MainMenu();
int ReadProfileData(char **ProfileData, FILE *infile);
void DayNode(char **ProfileData, int DayOfDiet, Profile *Pro, int MenuOption, int SaveNode, DayStats *Node);
void SetProfile(char**ReadData, Profile *User, DayStats *Node, int DaysOnDiet);
void AppendFromTail(DayStats *Tail);
.