String Array

Pages: 12
Part 2.

Down in "main":
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
int main()
{
    char name[25]{};  // <--- Why a character array and not a std::string? Also these 5 lines do not seem to be used in "main".
    char time1[25]{};
    char time2[25]{};
    char time3[25]{};
    string customer, phone_number;

    fstream movie;  // <--- Why ftream and not ifstream?
    movie.open("Movies.txt", ios::in);
    // <--- How do you know it is open?

    int seat_price{}, lines{};  // <--- ALWAYS initialize your variables.
    char seat_row{}, seat_column{}, response{}, r{}, r2{}, pay_res{}, reuse_response{}, selection_show{}, selection_movie1{}, seat_type{}, selection_role{};
    double remaining{}, cash{};

menu:  // <--- Should replace with a do/while or while loop.

    system("CLS");

    title();  // <--- Call the function that you have and do not duplicate code.

    cout << "                  ****************************************************************************************" << '\n';
    cout << "                                             MOVIE TICKET RESERVATION SYSTEM (MTRS)                       " << '\n';  // <--- The extra space after (MTRS) is not needed and does nothing.

    cout << "                  ****************************************************************************************" << "\n\n";
    //cout << '\n' << '\n';

    cout << "                  ========================        ==========================        ======================    " << '\n';
    cout << "                  * (A)  MOVIE BOOKING   *        * (B) TICKET CANCELATION *        * (C) SNACKS & DRINKS *     " << '\n';
    cout << "                  ========================        ==========================        ======================     " << "\n\n";
    //cout << '\n' << '\n' << '\n';

    cout << "                  ========================        ==========================        ======================     " << '\n';
    cout << "                  * (D)    MEMBERSHIP    *        * (E)     EMPLOYEES      *        * (F)   MANAGEMENT   *     " << '\n';
    cout << "                  *=======================        ==========================        ======================    " << '\n' << '\n' << '\n';
    cout << "                                                            INPUT : ";
    cin >> selection_role;

    selection_role = std::toupper(selection_role);  // <--- This will cut your while condition in half.

    while (selection_role != 'A' && selection_role != 'a' && selection_role != 'B' && selection_role != 'b' && selection_role != 'C' && selection_role != 'c' && selection_role != 'D' && selection_role != 'd' && selection_role != 'E' && selection_role != 'e' && selection_role != 'F' && selection_role != 'f')
    {
        cout << '\n';
        cout << "Sorry! You have entered a wrong selection. Please try again." << '\n' << '\n';
        cout << "Please select option: ";
        cin.ignore(std::numeric_limits <std::streamsize>::max(), '\n');
        cin >> selection_role;
    }

movies:
    if ((selection_role == 'A') || (selection_role == 'a'))

Lines 23 - 26 are duplicated. just call the "title" function here.

Something else you can do is:
1
2
3
4
5
6
7
8
9
10
11
12
13
cout <<
    "                  ========================        ==========================        ======================\n"
    "                  * (A)  MOVIE BOOKING   *        * (B) TICKET CANCELATION *        * (C) SNACKS & DRINKS *\n"
    "                  ========================        ==========================        ======================\n\n"
    "                  ========================        ==========================        ======================\n"
    "                  * (D)    MEMBERSHIP    *        * (E)     EMPLOYEES      *        * (F)   MANAGEMENT   *\n"
    "                  *=======================        ==========================        ======================\n\n"
    "                  ========================\n"
    "                  * (G)  Quit            *\n"
    "                  *=======================\n\n";

cout << "                  INPUT : ";
cin >> selection_role;

Here you have 1 "cout" 1 insertion operator, "<<", and the 9 lines of quoted strings are considered just 1 string. There is no need for a "cout" for each line. Also you can see that is is very easy to add to or edit.

Lines 8 - 10 I just copied the second group and deleted what was not necessary.

When the "cout" is done the "cin" will flush the buffer before taking any input. An advantage that you have.

Using "std::toupper()" before the while condition will cut this in half only having to check 1 case.

I stopped at the if statement because you only have 1 choice for now, but it looks like the rest of the code, some of which, should have its own if statement.And even some of that may work better in a different function.

Andy

Edit: Sorry had to fix some typos.
Last edited on
Just a tip, I'd put some of your && stuff on different lines, just to shorten up your code a bit.

Like so:
1
2
3
4
5
6
while (selection_role != 'A' && selection_role != 'a' &&
       selection_role != 'B' && selection_role != 'b' &&
       selection_role != 'C' && selection_role != 'c' &&
       selection_role != 'D' && selection_role != 'd' &&
       selection_role != 'E' && selection_role != 'e' &&
       selection_role != 'F' && selection_role != 'f')

Just makes it easier to read, groups stuff together, and it doesn't go across the entire page ;)

max
Last edited on
Infinitely better:

1
2
3
4
5
6
7
8
9
    while (true)
    {
        cout << "Select an option: ";
        cin >> role;
        cin.ignore(10000, '\n');
        role = toupper(role);
        if (role >= 'A' && role <= 'F') break;
        cout << "You have entered a wrong selection. Try again.\n\n";
    }

Code all the other inputs the same way.

BTW, don't beg the user (i.e., don't say "please").
Great idea, dutch, but be careful using toupper on "role"! I think he uses it elsewhere in his program, so it might be better to use it like so:
1
2
3
4
5
6
7
8
9
10
11
12
while (true)
{
     cout << "Select an option: ";
     cin >> role;

     cin.ignore(10000, '\n');
     
     if (toupper (role) >= 'A' && toupper (role) <= 'F')
          { break; }
     else
          { cout << "You have entered a wrong selection. Try again. \n\n"; }
}

I know it's only one line, but I just use the braces anyway. Makes it clearer to read for debugging. Hence the else in there as well.

Mathavan,
Of course, if you don't use it anywhere else in the program, just ignore me.
Have a good day!
max
Last edited on
For original food_drinks() function, update to my previous code to put the main processing into this function so that it can be called from elsewhere and to remove the main menu and incorporate this into the option to buy. Now consider with better error checking:

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
#include <string>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>

struct Menu {
	std::string name;
	double price {};
	size_t qty {};
};

enum {FOOD = 0, DRINK, MAXTYPE = DRINK};

using Men = std::vector<Menu>;
using Menus = Men[MAXTYPE + 1];

int getInt(const std::string& prm)
{
	int i {};

	while ((std::cout << prm) && (!(std::cin >> i) || std::cin.peek() != '\n')) {
		std::cout << "Not an integer\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return i;
}

void read(std::istream& is, Men& vm)
{
	for (Menu m; std::getline(is >> std::ws, m.name, '|') >> m.price; vm.push_back(m));
}

void display(const Menus& m)
{
	std::cout << std::setw(134) << std::setfill('-') << '\n';
	std::cout << "|                                                            SNACKS AND DRINKS                                                      | \n";
	std::cout << std::setw(134) << std::setfill('-') << '\n';
	std::cout << "|                      SNACKS AVALABLE                   |   PRICE   |                    DRINKS AVAILABLE              |   PRICE   |\n";
	std::cout << std::setw(134) << std::setfill('-') << '\n';
	std::cout << "|                                                        |           |                                                  |           |\n";

	auto& Food {m[FOOD]};
	auto& Drink {m[DRINK]};

	std::cout << std::setfill(' ') << std::left;

	for (size_t e = 0, lst = std::max(Food.size(), Drink.size()); e < lst; ++e) {
		if (e < Food.size())
			std::cout << "|(" << std::setw(2) << std::right << e + 1 << std::left << ".) " << std::setw(50) << Food[e].name << '|' << std::setw(11) << std::setprecision(2) << std::fixed << Food[e].price;
		else
			std::cout << '|' << std::setw(56) << ' ' << '|' << std::setw(11) << ' ';

		if (e < Drink.size())
			std::cout << "|(" << std::setw(2) << std::right << e + 1 << std::left << ".) " << std::setw(44) << Drink[e].name << '|' << std::setw(11) << std::setprecision(2) << std::fixed << Drink[e].price << "|\n";
		else
			std::cout << '|' << std::setw(50) << ' ' << '|' << std::setw(11) << ' ' << "|\n";
	}
}

void add(const Menus& m, Men& order)
{
	int types {};

	do {
		do {
			types = getInt("[Food = 1, Drink = 2, Receipt = 0] : ");
		} while ((types < 0 || types > 2) && (std::cout << "Invalid option\n"));

		if (types) {
			int opt {};

			do {
				opt = getInt("Enter menu number: ");
			} while ((opt < 1 || opt > m[types - 1].size()) && (std::cout << "Invalid menu number\n"));

			const int qty {getInt("Enter quantity: ")};

			order.push_back(m[types - 1][opt - 1]);
			order.back().qty = qty;
		}
	} while (types);
}

void receipt(const Men& order)
{
	double total {};

	std::cout << "\nReceipt\n\n";
	std::cout << std::setw(25) << "Name" << std::setw(10) << "Price" << std::setw(10) << "Quantity" << "Total\n";

	for (const auto& [nam, prce, qty] : order) {
		std::cout << std::setw(25) << nam << std::setw(10) << std::fixed << std::setprecision(2) << prce << std::setw(10) << qty << std::setw(10) << prce * qty << '\n';
		total += prce * qty;
	}

	std::cout << "\nTotal is " << total << '\n';
}

void food_drinks()
{
	std::ifstream foodfs("food.txt");
	std::ifstream drinkfs("drink.txt");

	if (!foodfs || !drinkfs) {
		std::cout << "Cannot open input files\n";
		return;
	}

	Menus menus {};
	Men order;

	read(foodfs, menus[FOOD]);
	read(drinkfs, menus[DRINK]);
	display(menus);
	add(menus, order);
	receipt(order);
}

int main()
{
	food_drinks();
}

For another way to do menus, consider this. It uses an array of menu text and the function to call for each item. This means you don't have multiple if statements or a long switch statement and is easily extendable.

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
include <iostream>
#include <string>
#include <limits>
#include <iterator>
#include <cctype>

using Funs = void(*)();

void f1() { std::cout << "f1\n"; }
void f2() { std::cout << "f2\n"; }
void f3() { std::cout << "f3\n"; }
void f4() { std::cout << "f4\n"; }

struct Menus {
	std::string name;
	Funs func;
};

char getChar(const std::string& prm)
{
	char ch {};

	while ((std::cout << prm) && (!(std::cin >> ch) || std::cin.peek() != '\n')) {
		std::cout << "Not a char\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return ch;
}

int main()
{
	const Menus mens[] {{"Option 1", f1}, {"Option 2", f2}, {"Option 3", f3}, {"Option 4", f4}};
	char opt {};

	do {
		char maxopt {'A'};

		std::cout << '\n';
		for (; const auto & [name, func] : mens)
			std::cout << maxopt++ << ". " << name << '\n';

		std::cout << "Q. Quit\n";

		do {
			opt = static_cast<char>(std::toupper(static_cast<unsigned char>(getChar("\nEnter option: "))));
		} while (((opt < 'A') || ((opt >= maxopt) && (opt != 'Q'))) && (std::cout << "Invalid option\n"));

		if (opt != 'Q')
			mens[opt - 'A'].func();

	} while (opt != 'Q');
}

Topic archived. No new replies allowed.
Pages: 12