Help with a Loop

Hello, I'm currently making a program that reads off a file and prints a list of movies playing within a certain date range. However, I am struggling to figure out how to keep the loop from dropping out if the starting date is not equal to a date a movie is playing.

I have a txt file with movies playing at certain dates, however there isn't a movie everyday. If I input a starting date into this part of my program that doesn't equal one of the dates on the text file this loop I made will drop out straight away.

If anyone with a better eye or understanding can help I'd really appreciate it. 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
{
	Text text;
	ifstream readdates;
	readdates.open("ShowDates.txt", ifstream::in);
	if (readdates.is_open() != true)
	{
		cout << "File open failed. Press any key to close application.";
		cin.ignore();
	}
	cout << "\nPlease input the date you want to search from, in a DD/MM/YY format.";
	cin >> a;
	if (a.find('/') == string::npos)
	{
		cout << "Please input a valid date.";
		getdates();
	}
	cout << "\Now, please input the date you want to search to, in a DD/MM/YY format.";
	cin >> b;
	if (b.find('/') == string::npos)
	{
		cout << "Please input a valid date.";
		getdates();
	}
//############################################################
//Here is my problem
//########################################################
	do
	{
		readdates >> date >> name >> time;
		//cout << "\ndate: " << date << "from: " << a << "to: " << b;
		if (date != a)
		{
			//if it hasn't reached a we do nothing
		}
		else
		{
			cout << "Date                    Name			            Time";
			//if it has reached a we start this loop
			while (date != b)
			{
				readdates >> date >> name >> time;
				replace(name.begin(), name.end(), '_', ' ');
				cout << "\n" << date << "		" << name;
				text.middle(name.length());
				cout << time;
			}
		}//which drops out here
	} while (date != b );
	cin.ignore();
}
What does "loop dropping out" mean? I'm not familiar with that. Are you saying the loop is ending earlier than you expect, or you are saying it's looping too much?

Just after a cursory glance at your code, it sounds like it's the latter.

If you want the loop to correctly end at some point, I would structure your outer loop to look something like this instead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while (readdates >> date >> name >> time)
{
    // the condition in the while loop means we successfully retrieved information
    // from the stream and put it in "date", "name", and "time"

    if (date == a) // start date found
    {
        while (readdates >> date >> name >> time)
        {
            if (date == b)
            {
                // end date found
            }
        }
    }
}


PS: I suggest that you use readable variable names. "a" and "b" are not good variable names. It would make much more sense if you named them "from_date" and "to_date" or something of that nature.

____________________________

After taking another look, I think you might want to make your dates be comparable.
That way, you don't need an exact match, you can just say "date >= start_date" or "date <= end_date". This can be done easily if you format your dates to be "YYYYMMDD".
Last edited on
Hello,

Thank you for your reply and tips, they are helpful. I am very lazy with variable names for certain things like this one.

My loop is dropping out much sooner than I want.

For example, currently there is movies playing on: 07/02/20, 08/02/20, & 09/02/20. If I input 06/02/20 (no movies on my list for this date) as my starting date (a), I won't get anything printed on the screen. However, if I input 07/02/20 as into my starting date (a) then it'll print everything up to the ending date just fine.
Last edited on
If I input 06/02/20 (no movies on my list for this date) as my starting date (a), I won't get anything printed on the screen.
Right, I think I understand. So the (data != a) branch isn't being hit, and there's nothing else happened in your while loop besides the date being updated, so if the date is never equal to a, it won't go into the the inner loop (line 39).

I think a different approach should be taken.

You get the start date and the end date from the user. That's fine, but as I said earlier, you need some way to compare dates for more than just equality to properly start/end your iteration.

I can't tell if your date format is MM/DD/YY or DD/MM/YY, but either way it isn't good for comparison. For example, 121201 (December 12, 2001) would be "greater than" 010120 (January 1st 2020) in this format.

What I would do is convert the date strings into formats that can compared using < and > (less than, greater than).
So for example, if your date is 25/12/20, this should be converted into 201225 (Year, Month, Day).
This way, the string "201225" will compare as being greater than the string "191225" for purposes of comparing against the start and end dates.

After you do the proper conversion, your loop can be something similar to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
start_date = /* get start date */
convert_to_YYMMDD(start_date)

end_date = /* get end date */
convert_to_YYMMDD(end_date)

while (read next movie from file)
{
    convert_to_YYMMDD(movie_date)
    if (movie_date >= start_date && movie_date <= end_date)
    {
        // print movie
    }
}


At this point, the challenge becomes properly converting DD/MM/YY format to YYMMDD. This requires some parsing of strings. (Alternatively, a "Date" class could be made, with integer fields for year, month, and day, and comparison operators).

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
// Example program
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

// converts "DD/MM/YY" to "YYDDMM" to allow proper string comparison
// (note that input must contain the slashes)
// No error handling is done here... feel free to add some
string convert_slashed_DDMMYY_to_YYMMDD(const string& date)
{
    istringstream iss(date);
    
    string day;
    getline(iss, day, '/');
    
    string month;
    getline(iss, month, '/');
    
    string year;
    getline(iss, year, '/');
    
    // reorder (with slashes now removed):
    return year + month +  day;
}

int main()
{
    std::cout << convert_slashed_DDMMYY_to_YYMMDD("25/12/20") << '\n';
}
Last edited on
Hi,

I've implemented what you've suggested and I see what you mean now. This works well. I didn't understand why we had to convert the date to begin with, but now I see.

Thank you for your time.
Topic archived. No new replies allowed.