1

Тема: C++ після повторного виклику меню, не працює вихід але продовжує ввід

після повторного виклику меню, не працює вихід але продовжує ввід. Якщо ж виходити з програми зразу то все працює, але якщо я введу дані, повернусь в меню, то вихід не працює, замість виходу програма продовжує ввід данних, не розумію в чому проблема
P.S.:
також вислухаю аргументовану критику на рахунок деяких реалізацій(можливо підкажете щодо динамічної структури, поки оюмежуюсь таким варіантом як є(вектори і файли не використовувати, обмеження завдання))

#include <iostream>
#include <stdlib.h>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <locale>
#include <Windows.h>
#include <utility>
#include <algorithm>
using namespace std;
int n = 0;

struct vust {
    char Name[20];
    struct date {
        int day;
        int month;
        int year;
    }Date;
    int tickets; 
    int price;
}Group[100];

void enter(), print(), sortP(), sortN(), display(), menu(), display2();
int  quit();

int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    menu();
    /*char choice;
    for (;;) {
        choice = menu();
        switch (choice) {
        case 'e': enter();
            break;
        case 'n': sortN();
            break;
        case 'p': sortP();
            break;
        case 'r': ;
            break;
        case 'd': ;
            break;
        case 'q': quit();
            break;
        }
    }
    system("pause");*/
}
void menu()
{
    char ch;
    cout << "\n";
    do {
        cout << "\n(E)Ввести данні про виставу\n";
        cout << "(N)Сортувати за назвою вистави\n";
        cout << "(P)Сортувати за ціною\n";
        cout << "(D)Вивести всі вистави\n";
        cout << "(Q)Вийти з програми\n";
        cout << "(T)Вивести вистави конкретного дня\n";
        cout << "Виберіть команду: ";
        cin >> ch;
    } while (!strchr("enptdq", tolower(ch)));
    switch (ch)
    {
    case 'e': enter();
        break;
    case 'n': sortN();
        break;
    case 'p': sortP();
        break;
    case 'q': quit();
        break;
    case 'd': display();
        break;
    case 't': display2();
        break;
    }
    //return tolower(ch);
}



 void enter()
{
    char c;
    for (int i = n; i < sizeof(Group); i++)
    {
        cout << endl << "Введіть назву вистави: ";
        cin >> Group[i].Name;
        cout << "Введіть день вистави: ";
        cin >> Group[i].Date.day;
        cout << "Введіть місяць вистави: ";
        cin >> Group[i].Date.month;
        cout << "Введіть рік вистави: ";
        cin >> Group[i].Date.year;
        cout << "Введіть кількість квітків: ";
        cin >> Group[i].tickets;
        cout << "Введіть ціну квитка: ";
        cin >> Group[i].price;
        n += 1;
        do {
            cout << "\n(M)Повернутись в меню";
            cout << "\n(E)Продовжити вводити дані";
            cout << "\nВиберіть команду: ";
            cin >> c;
        } while (!strchr("em", tolower(c)));
        switch (c)
        {
        case 'e': continue;
            break;
        case 'm': menu();
            break;
        }
    }
    
}
 void sortP()
 {
     for (int j = 0; j < n; j++)
     {
         for (int i = 0; i < n-1-j; i++)
         {
             if (Group[i].price > Group[i + 1].price)
             {
                 swap(Group[i], Group[i + 1]);
             }
         }
     }
     display();
     
 }

 void sortN()
 {
     for (int j = 0; j < n; j++)
     {
         for (int i = 0; i < n-1-j; i++)
         {
             if (strcmp(Group[i].Name, Group[i+1].Name) > 0)
             {
                 swap(Group[i], Group[i + 1]);
             }
         }
     }
     display();
 }

 void display()
 {
     if (n == 0)
         cout << "\nСписок пустий!\n";
     for (int i = 0; i < n; i++)
     {
         cout << endl << "\nНазва вистави: "; cout << Group[i].Name;
         cout << endl << "День вистави: "; cout << Group[i].Date.day;
         cout << endl << "Місяць вистави: "; cout << Group[i].Date.month;
         cout << endl << "Рік вистави: "; cout << Group[i].Date.year;
         cout << endl << "Кількість квітків: "; cout << Group[i].tickets;
         cout << endl << "Ціна квитка: "; cout << Group[i].price;
     }
     menu();
 }

 int quit()
 {
     return 0;
 }

 void display2()
 {
     int d, m, y, k = 0;
     cout << "\n\nВведіть дату";
     cout << "День: "; cin >> d;
     cout << "Місяць: "; cin >> m;
     cout << "Рік: "; cin >> y;
     for (int i = 0; i < n; i++)
     {
         if (d == Group[i].Date.day && m == Group[i].Date.month && y == Group[i].Date.year) 
         {
             cout << endl << "\nНазва вистави: "; cout << Group[i].Name;
             cout << endl << "День вистави: "; cout << Group[i].Date.day;
             cout << endl << "Місяць вистави: "; cout << Group[i].Date.month;
             cout << endl << "Рік вистави: "; cout << Group[i].Date.year;
             cout << endl << "Кількість квітків: "; cout << Group[i].tickets;
             cout << endl << "Ціна квитка: "; cout << Group[i].price;
             k = 1;
         }
     }
     if (k == 0)
         cout << "\nВистав у цей день немає!\n";
     menu();
     
 }
 

2

Re: C++ після повторного виклику меню, не працює вихід але продовжує ввід

notsemka написав:
struct vust {
    char Name[20];
    struct date {
        int day;
        int month;
        int year;
    }Date;
    int tickets; 
    int price;
}Group[100];

Назва структури, звісно ж, говорить сама за себе.. А, чому Name з великої літери, а tickets та price з малої? Вас самих це не плутає?
------------------------------------

notsemka написав:
void enter(), print(), sortP(), sortN(), display(), menu(), display2();
Прихований текст

https://media.makeameme.org/created/why-just-why-5cb202.jpg

------------------------------------

notsemka написав:
------------------------------------
cout << "\n(E)Ввести данні про виставу\n";

Данні, це типу чиєсь ім'я? *SCRATCH*
------------------------------------

do {
    cout << "\n(E)Ввести данні про виставу\n";
    ...
    cin >> ch; // Якщо я введу ось тут літеру 'E', як ви просите
} while (!strchr("enptdq", tolower(ch)));
switch (ch)
{
case 'e': enter(); // чи потраплю я тоді сюди?
    break;
...
}

Як ви гадаєте?
------------------------------------

 void enter()
{
    char c;
    for (int i = n; i < sizeof(Group); i++) // sizeof(Group) - точно робить не те, що ви думаєте
    {
        cout << endl << "Введіть назву вистави: ";
        cin >> Group[i].Name;
        cout << "Введіть день вистави: ";
        cin >> Group[i].Date.day;
        cout << "Введіть місяць вистави: ";
        cin >> Group[i].Date.month;
        cout << "Введіть рік вистави: ";
        cin >> Group[i].Date.year;
        cout << "Введіть кількість квітків: "; // квИтків
        cin >> Group[i].tickets;
        cout << "Введіть ціну квитка: ";
        cin >> Group[i].price;
        n += 1;
        do {
            cout << "\n(M)Повернутись в меню";
            cout << "\n(E)Продовжити вводити дані";
            cout << "\nВиберіть команду: ";
            cin >> c;
        } while (!strchr("em", tolower(c)));
        switch (c)
        {
        case 'e': continue;
            break;
        case 'm': menu(); // << ось тут ваша проблема
            break;
        }
    }
    
}

Після того, як ф-я menu() завершить своє виконання, ви повертаєтесь назад у цикл, де відбудеться його наступна ітерація з вводом.
------------------------------------

notsemka написав:

P.S.:
також вислухаю аргументовану критику на рахунок деяких реалізацій(можливо підкажете щодо динамічної структури, поки оюмежуюсь таким варіантом як є(вектори і файли не використовувати, обмеження завдання))

Що таке динамічна структура?

Подякували: leofun01, mimik2

3

Re: C++ після повторного виклику меню, не працює вихід але продовжує ввід

wander написав:

Після того, як ф-я menu() завершить своє виконання, ви повертаєтесь назад у цикл, де відбудеться його наступна ітерація з вводом.

подякувава

4

Re: C++ після повторного виклику меню, не працює вихід але продовжує ввід

notsemka написав:

void enter(), print(), sortP(), sortN(), display(), menu(), display2();

що саме не так з цим? а на рахунок дрібничок, теж дякую, проста неуважність)

5

Re: C++ після повторного виклику меню, не працює вихід але продовжує ввід

notsemka написав:
void enter(), print(), sortP(), sortN(), display(), menu(), display2();

що саме не так з цим?

З точки зору мови програмування - все добре.
З точки зору людини, яка читатиме ваш код - пекло.
Ви ж пишете на С++, вірно? Нащо вам ці попередні оголошення ф-й? Описуйте їх прямо на місці

void enter() {
    бла-бла-бла
}
void menu() {
    бла-бла-бла
}
...
int main() {
    enter();
    menu();
    ...
}

А, якщо і дуже тре попередньо оголосити, то не полінуйтесь і оголосіть їх окремо

// Можна навіть додати якогось коментаря, що ця ф-я робить
void enter();

// Можна навіть додати якогось коментаря, що ця ф-я робить
void menu();

Це полегшить вам життя і тому, хто читатиме ваш код.

notsemka написав:

а на рахунок дрібничок, теж дякую, проста неуважність)

Більшість з того не є дрібничками. Назви змінних, функцій, структур у вас - це фактично якісь шифри. Якщо з назв enter чи menu ще можна здогадатись, що воно робить, то що роблять display та display2? Чому там 2 у назві? І тому подібне..

Далі, по функціоналу.. Ваш код містить потенційно невизначену поведінку (UB - undefined behavior).

for (int i = n; i < sizeof(Group); i++) // як тільки n стане більше за розмір масиву (100 у вашому випадку), ви отримаєте UB
...
for (int i = 0; i < n; i++) // як і у всіх інших циклах, які ітеруються по n