Scheduling Program Question

I'm attempting to create a program where the user can create a checklist. The user can then check off each activity that they have completed by inputting the number of the activity.
(ex:
1. brush teeth
2. shower
3. go to work
)

The checklist should reset after the user is finished checking off completed items and the program should move on to the next day (i.e. once the user has entered "done").

I am having problems resetting the checklist at the end of each day. The total number of activities in the checklist seems to be constant after the first iteration. (If I entered 5 activities on day 1, for some reason I am limited to a max of 5 activities on day 2)

You'll see what I mean if you run it. Hopefully my beginner's code isn't too messy and crazy. Thank you! ^_^


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <iostream>
#include <string>
#include <conio.h>
#include <windows.h>
#include <sstream> 
#include <ctime>

using namespace std;

void inputCheckList(string*, int, int);
void checkList(string*, string, int*, int, int);


int main() {
	string act[100];
	string actCheck;
	int count = 1;
	int totalItems = 0;
	int numArray[100];
	int day = 1;

	srand(time(NULL));

	do {

		cout << "Day " << day << endl;
		cout << "Create your checklist (Enter 'done' when you are finished):" << endl;

		inputCheckList(act, count, totalItems);						//call for the getCheckList function to get the user's checklist
		checkList(act, actCheck, numArray, count, totalItems);        //call for the checkList function

		cout << "//////////////////////////////////////////////////////////////////////////////" << endl;

		day++;

	} while (1);

	return 0;
}


//This function is responsible for taking user input to create a checklist.

void inputCheckList(string* act, int count, int totalItems) {
	do {
		cin >> act[count];
		if (act[count] == "done") {
			totalItems = count;

			cout << "Activities for the day: " << endl;
			for (count = 1; count < totalItems; count++) {
				cout << count << ". " << act[count] << endl;
			}
			

		}
		else count++;
	} while (count < 100 && act[count] != "done");

}


//This function turns the actCheck string into an integer and asks the user to input a number corresponding to an activity that they have completed.
//Each activity that the user has entered into the checklist will have a corresponding number. (ex: 1. brush teeth; 2. shower)
//It will also grant varrying amounts of exp for each activity that the user completes.

//When the user enters "done", the program will display the completed tasks and the user's total exp.

void checkList(string* act, string actCheck, int* numArray, int count, int totalItems) {

	int num = 0;
	int test = 0;
	cout << "Alright, what has been completed? (Enter the # of each activity that you complete. Enter 'done' to proceed): " << endl;
	do {

		cin >> actCheck;                // The user enters the number of the activity that they completed (ex: 1. brush teeth; 2. shower)
										// I did not user an int here because I want the input stream to end when the user inputs "done" (just for funsies)
		//totalItems = count;

		if (actCheck == "done") {


			//if the user inputs "done", start a for loop that sets "int placeHolder" equal to the value in numArray[count] for each iteration of count.
			//This is so that I can use each numArray[count] as a regular integer. The "placeHolder" integer will be used as the count for "act".

			cout << "Ok, here's what you finished: " << endl;
			for (count = 1; count < totalItems; count++) {
				int placeHolder = numArray[count];
				if (placeHolder > 0) {
					cout << numArray[count] << ". " << act[placeHolder] << endl;
				}
			}
		}
		else {
			stringstream geek(actCheck);          //input from string actCheck is converted into an integer "num" at this point
			geek >> num;

			numArray[count] = num;					//numArray[count] is set to the current value of "num"

			cout << act[num] << " x" << endl;
			count++;

		}

	} while (count < 100 && actCheck != "done");

}
Last edited on
in c++, the first array location is [0] not [1]. its ok to oversize and index by 1 if there is a good reason, like converted code from another language that you want to keep similar to the original, but generally you would not index from 1 in new code.

to reset, I think you need to set count to 1 and totalitems back to 0.
I believe this is all you need to do: calling input again will over-write the existing strings and handle the counters, so even though there is stale data in your arrays, you should not be able to get to it and do not need to waste the cpu time to clear it out.

@cupcake007

Besides resetting count and totalitems, you needed to reset act[], to remove the word 'done', as the program is looking for that keyword.
I got rid of totalitems variable, as it wasn't really needed, Also, since you're not needing random numbers, you could remove the srand() on your line 22, along with #include <ctime> and #include <conio.h> . Program will work fine without them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <string>
//#include <conio.h>
#include <windows.h>
#include <sstream> 
//#include <ctime>

using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::stringstream;


void inputCheckList(string act[100], int & count);
void checkList(string act[100], string, int numArray[100], int & count);


int main() {
	string act[100];
	string actCheck;
	int count;
	int numArray[100];
	int day = 1;

	// srand((unsigned)time(0)); // Why?? - Not really needed

	do {
		count = 0; // Reset count variable
		cout << "Create your checklist (Enter 'done' when you are finished):" << endl;
		cout << "Day " << day << endl;
		inputCheckList(act, count);						//call for the getCheckList function to get the user's checklist

		checkList(act, actCheck, numArray, count);        //call for the checkList function

		cout << endl << "//////////////////////////////////////////////////////////////////////////////" << endl << endl;

		day++;

	} while (1);

	return 0;
}


//This function is responsible for taking user input to create a checklist.

void inputCheckList(string act[100], int &count)
{
	int num;

	for (num=0;num < 100;num++)
		act[num] = " ";
	do {
		cout << count+1 << " > ";
		getline(cin, act[count]);

		if (act[count] != "done")
		{
			count++;
		}
	} while (count < 100 && act[count] != "done");
}


//This function turns the actCheck string into an integer and asks the user to input a number corresponding to an activity that they have completed.
//Each activity that the user has entered into the checklist will have a corresponding number. (ex: 1. brush teeth; 2. shower)
//It will also grant varrying amounts of exp for each activity that the user completes.

//When the user enters "done", the program will display the completed tasks and the user's total exp.

void checkList(string act[100], string actCheck, int* numArray, int &count)
{

	int num;

	cout << "Alright, what has been completed? (Enter the # of each activity that you complete. Enter 'done' to proceed): " << endl;

	for(num = 0; num < count; num++)
	{
		cout << num+1 << " > " << act[num] << endl;
		numArray[num] = 0;
	}
	do
	{

		cin >> actCheck;                // The user enters the number of the activity that they completed (ex: 1. brush teeth; 2. shower)
		// I did not user an int here because I want the input stream to end when the user inputs "done" (just for funsies)
		//totalItems = count;

		if (actCheck == "done") {


			//if the user inputs "done", start a for loop that sets "int placeHolder" equal to the value in numArray[count] for each iteration of count.
			//This is so that I can use each numArray[count] as a regular integer. The "placeHolder" integer will be used as the count for "act".

			cout << "Ok, here's what you finished: " << endl;
			for (num = 0; num < count; num++) 
			{
				if (numArray[num] > 0)
				{
					cout << num+1 << " > " << act[num] << endl;
				}
			}
		}
		else 
		{
			stringstream geek(actCheck);          //input from string actCheck is converted into an integer "num" at this point
			geek >> num;
			num--;
			if(numArray[num] == 1)
				cout << act[num] << " already performed!" << endl;
			else
				numArray[num] = 1;					//numArray[count] is set to the current value of "num"
			for (num = 0; num < count; num++) 
			{
				if (numArray[num] > 0)
				{
					cout << num+1 << " > " << act[num] << " x" << endl;
				}
				else
					cout << num+1 << " > " << act[num] << endl;
			}
		}
	} while (count < 100 && actCheck != "done");
	cin.clear();// Restore input stream to working state
	cin.ignore ( 100, '\n' ); // Get rid of any garbage that user might have entered
}
I disagree.
as I understood input:

count coming in would be 0, from reset.

do {
cin >> act[count]; //overwrite existing string.
if (act[count] == "done") //check value that was just entered.
...
else count++; //move counter.
} while()

if act were not reinitialized, there is NO way to get to that old done value that I can see because the cin statement is before the check. And, the other routines are using some sort of check that we can only assume is in the bounds of the current total count? Its safer to clear it, of course, but I don't think it breaks anything assuming there isnt a bug that can read locations not in play (in which case, there is a bug and clearing the array only masks it, does not fix it).

OP, what happens if the user decides to set task #23 to completed when there are only 5 tasks for that day? Or item 999999999? Is this accounted for with actcheck?
Last edited on
@jonnin

According to the OP's original program
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//This function is responsible for taking user input to create a checklist.

void inputCheckList(string* act, int count, int totalItems) {
	do {
		cin >> act[count];
		if (act[count] == "done") {
			totalItems = count;

			cout << "Activities for the day: " << endl;
			for (count = 1; count < totalItems; count++) {
				cout << count << ". " << act[count] << endl;
			}
			

		}
		else count++; // count is increased by one
// if act[count] is now pointing at "done", we jump out of do\while loop

	} while (count < 100 && act[count] != "done");

}
Right. Which does not look past count at stale data, so it would not register an old 'done', ? Am I missing something here?
@jonnin

Yes, I believe you are missing something. Let's say that the user enters 5 things into the schedule array, with number 6 being "done". On day 2, when (s)he starts entering data, count is increased at each entry. Count is increased by one AFTER the entry. The while part is checking what is IN act[count] BEFORE the next entry is made, SO when count equals 6, which is "done", the while loop is satisfied, and ends, not allowing another entry by the user.

Did you try running the original code, and seeing if you can go past the first count of entries for day 2? I did, and couldn't.
No, I generally don't download and compile this stuff.
But I see it, and that makes sense. Thanks for pointing at it, I can be slow at times.

Its a bug. the count++ should be moved to the while index and that else removed.
while (count < 100 && act[count++] != "done");

even if you clear the array, its looking at one past valid entries there.
@jonnin

I don't know who reported you. It wasn't me. Hopefully it was just an error on someone's part, and not by the OP

I don't think of you or anyone on this forum, as slow. A lot of what is perceived, is how things are read. I did read your second post, and changed the coding I have, to check for an entry higher than count or lower than 0, and output some text accordingly, and not just label that activity, as done. Thanks for bringing that to my attention, even it doesn't help the OP at the moment.
Last edited on
FWIW The following functional breakup into primitive functions avoids a lot of the pitfalls of searching through a maze to debug bad outcomes.

A reset is a simple loop through changing the status.

It's not complete - there's no delete function - just demonstrates another approach where you can perhaps zero in on problems more efficiently.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <string>

void addTask(std::string*, bool*, int&);
void showSchedule(std::string*, bool*, int&, const char);
void changeStatus(bool*, int, const int aTop);
void displayATask(const std::string*, const bool*, const int);

const int no_tasks{100};

int main()
{
    // SETUP DATA MODEL
    int current_size{0};
    
    std::string daily_schedule[no_tasks]{};
    bool complete[no_tasks]{false};
    
    // GENERATE SOME TASKS
    for(int i = 0; i < 3; i++)
        addTask(daily_schedule, complete, current_size);
    std::cout << '\n';
    
    char status{};
    status = 'A'; // fo All
    
    // PLAY AROUND ...
    // (A)
    showSchedule(daily_schedule, complete, current_size, status);
    
    // (B)
    changeStatus(complete, 1, current_size);
    showSchedule(daily_schedule, complete, current_size, 'A');
    
    // (C)
    status = 'I'; // for Incomplete
    showSchedule(daily_schedule, complete, current_size, status);
    addTask(daily_schedule, complete, current_size);
    
    status = 'A';
    showSchedule(daily_schedule, complete, current_size, status);
    
    // (D)
    status = 'C'; // for Incomplete
    showSchedule(daily_schedule, complete, current_size, status);
    
    return 0;
}


void addTask(std::string* aSchedule, bool* aComplete, int& aTop)
{
    std::cout << "Enter task: ";
    std::string aTask;
    getline(std::cin,aTask);
    
    aSchedule[aTop] = aTask;
    aComplete[aTop] = false;
    
    aTop++;
    
    return;
}


void showSchedule
(std::string* aSchedule, bool* aComplete, int& aTop, char aStatus)
{
    for(int i = 0; i < aTop; i++)
    {
        if(aStatus == 'A')
            displayATask(aSchedule, aComplete, i);
        
        if(aStatus == 'C')
            if( aComplete[i] == true)
                displayATask(aSchedule, aComplete, i);
        
        if(aStatus == 'I')
            if( aComplete[i] == false)
                displayATask(aSchedule, aComplete, i);
    }
    std::cout << '\n';
    
    return;
}


void changeStatus
(bool* aComplete, int aTaskNo, const int aTop)
{
    if(aTaskNo < 0 or aTaskNo > aTop )
        std::cout << "ERROR: task outside range\n";
    else
        aComplete[aTaskNo] = !aComplete[aTaskNo];
    
    return;
}


void displayATask
 (const std::string* aSchedule, const bool* aComplete, const int aTaskNo)
{
    std::cout
    << "Task no: " << aTaskNo << ' '
    << aComplete[aTaskNo] << ' '
    << aSchedule[aTaskNo] << '\n';
    
    return;
}
I don't know who reported you.

There seems to be a madman reporter on the loose.
Quite possibly Carol - still got the shits for me picking on her ungrammatical sentence constructions ;)
Topic archived. No new replies allowed.