LinuxForum.Fans
Тема

Объясните в чём ошибка.

Автор: Eeb_ei4m 31 сообщений 4176 просмотров
12.01.2015 14:27 · отредактировано #409215
text
#include <iostream>
#include <cstdlib> // for clear
using namespace std;

int Menu (void) {

char selection;

cout << "\n\t Меню:\n\n"; cout << " 1) Выбор первого пункта\n"; cout << " 2) Выбор второго пункта\n"; cout << " 3) Выбор третьего пункта\n"; cout << " 4) Выбор четвёртого пункта\n"; cout << " 5) Выход\n\n"; cout << "\tВаш выбор: ";

cin >> selection;

switch (selection) {

case '1': { system("clear"); cout << "Команды первого пункта\n"; }

break;

case '2': { system("clear"); cout << "Команды второго пункта\n"; }

break;

case '3': { system("clear"); cout << "Команды третьего пункта\n"; }

break;

case '4': { system("clear"); cout << "Команды четвёртого пункта\n"; }

break;

case '5': { cout << " Выход\n"; }; return 0;

default: { cout << "\n Не верный выбор\n"; }

}

cout << "\n";

}

int main () {

system("clear");

Menu ();

}

12.01.2015 15:09 · отредактировано #409219
"Eeb>ei4m" написал:
cin >> selection;

если вы хотите поймать один символ, то логичнее загрузить всю строку

text
std::string s;
cin>> s;

и потом брать первый символ

text
switch(s[0]){

PS:

text
       case '2': {
                      system("clear"); cout << "Команды второго пункта\n";
                  }

{скобки} тут не нужны.

PPS:
а за ЭТО:

system("clear");

надо УБИВАТЬ.

Если вы уж так хотите вывод в терминал типа как в MS-DOS, то используйте ncurses. Учтите, что clear всё равно зависит от libncursesw.so.5, и без неё работать не будет. Т.е. вы по любому к ncurses обращаетесь, но через задницу.

12.01.2015 16:49 · отредактировано #409235

Спасибо за ответ, только жаль что я почти ничего не понял.

По пунктам:

1) Вы не могли бы повторить то же но развёрнуто или без слэнга?

2) Я так и не понял в какой части содержится ответ на мой вопрос ( в чём ошибка), почему несмотря на отсутствие break у default
происходит выход?

3)

если вы хотите поймать один символ
Я вообще никого ловить не собирался, в этой части совсем не понял ответа.

4)
{скобки} тут не нужны.
Как Вы их называете {скобки} нужны, потому что это анонимная функция (блок кода) и в рабочем варианте там много чего. А зесь они просто не мешают.

5)
Если вы уж так хотите вывод в терминал типа как в MS-DOS
Не понимаю где Вам приснился MS-DOS. Мне нужен аналог /usr/bin/clear который я использовал в bash. Если знаете как сделать лучше то подскажите как, и почему нельзя как у меня. В конечном варианте нужна раскраска, это делается с использлванием sys-libs/ncurses?

6) Слишком много развелось в интернете дистрофичных очкариков которые с лёгкостью оперируют словами типа: "убить" и "задница".
Меня лично это настораживает. (Среди моих знакомых очень много воевавших или сидевших людей но от них я такого никогда не слышал публично)

Повторю вопрос, где у меня ошибка? Почему происходит выход из меню?
12.01.2015 20:44 #409280
"Eeb>ei4m" написал:
почему несмотря на отсутствие break у default происходит выход?

Встречный вопрос: почему с наличием или отсутствием break в switch default выход не должен происходить? Цитата из стандарта или учебника в качестве ответа вполне подойдёт.

12.01.2015 20:57 #409284

Чесно? Понятия не имею. Давайте я лучше что-нибудь на баше сделаю... Не видел нужных примеров в учебнике. Не смог найти нужной документации.
Написал как пришло в голову и задал на форуме вопрос.
На баше я бы использовал цикл do while .
Это первая попытка. Я не могу понять логику. Где вход где выход. За последний месяц прочитал кучу всего по С++.
И начинаю думать что отсутствие типов переменных в баше не такое уж и зло.

Вы бы не боялись прослыть не остроумными а просто указали на ошибку.

12.01.2015 21:10 · отредактировано #409287
bormant написал:
[quote="Eeb>ei4m"]почему несмотря на отсутствие break у default происходит выход?

Встречный вопрос: почему с наличием или отсутствием break в switch default выход не должен происходить? Цитата из стандарта или учебника в качестве ответа вполне подойдёт.[/quote]
возвращаться к меню надо в цикле? Блин! Эту бы подсказку 6 часов назад. Типа дойди сам? Я задал вопрос с целью экономии времени.
Спасибо.

12.01.2015 21:28 · отредактировано #409292

Чем можно заменить команды bashbuiltins?

13.01.2015 10:32 #409418

[OFFTOP]
Классный вопрос.....
Ошибки то нет. Программа работает так как и должна работать (насколько можно судить по коду). Или задача была ОС написать?
"Прочитал много учебников", "непонял почему выходит, хотя break не стоит"... Хм, а я вообще не помню букваря в котором у default оно есть.
"На баше бы использова do while", "Прочитал много учебников"....... Блин, я уж думал, что затяжной проект на php мне окончательно мозг поел. Спросил у гугла - не не поел..... Точно в этих двух цитатах, что то не правильное.
[/OFFTOP]

13.01.2015 10:33 #409420

Упс.. автор заблокированю

13.01.2015 11:55 #409428

"voral" написал:
Хм, а я вообще не помню букваря в котором у default оно есть.
хороший тон предполагает ставить break после default'а.
Если не ошибаюсь, в K&R есть.
Но это не важно.

Самое смешное в другом: Я собрал программу ТСа, и ВНЕЗАПНО:

Она РАБОТАЕТ.
13.01.2015 12:41 #409433
drBatty написал:

Если не ошибаюсь, в K&R есть.

Да, действительно. Хм.... В памяти дырка.....

13.01.2015 16:40 #409456
"voral" написал:
автор заблокирован

Да, до 14.01.2015.

13.01.2015 20:45 #409496

drBatty написал:
[quote="voral"]Хм, а я вообще не помню букваря в котором у default оно есть.
хороший тон предполагает ставить break после default'а.
[/quote]

Единственное, что требует ставить там break - так это только хороший тон. А так - это совершенно лишнее в конструкции case слово. Что есть там бреак, что нет его - по любому управление будет передано следующему после case {} оператору. И никуда иначе.
13.01.2015 21:08 #409498

"Cruiser78" написал:
Единственное, что требует ставить там break - так это только хороший тон.
этого мало?

"Cruiser78" написал:
А так - это совершенно лишнее в конструкции case слово.
да, лишнее. Без него тоже работает. Вот только сишка — это вам не пхп и не сишарп. Тут нужно писать код аккуратно и правильно.
14.01.2015 00:49 · отредактировано #409522

А я вот, честно, даже "понять" не могу "хорошести" тона. Уже просто даже это железобетонно сидит, что default в конце и после него завершается case.... Вот только по вашей наводки глянул в К&Р и вновь "узнал" и что break "хороший тон" и что после default можно писать еще case :).....

Не, я конечно понимаю, работа в команде чужой код.... Но мне бы точно по глазам резанул case после default :)

Ну вот, теперь, когда нибудь, в момент зашкаливания лени вколбашу case после default :).

В прочем, писать еще один break не в лом. пусть будет. Пусть я буду чуть более воспитанным :)

14.01.2015 00:52 #409523
"Cruiser78" написал:
Что есть там бреак, что нет его - по любому управление будет передано следующему после case {} оператору. И никуда иначе.

Не, ну если предположить совсем быдлокод, то после default можно вставить еще case..... И тогда break нужен.... Ну если это не "мега-ход" с "обдуманным" отсутствием break....

14.01.2015 07:25 #409531

"voral" написал:
и что после default можно писать еще case
default/case это просто метка для goto, которое тут называется switch.

"voral" написал:
Но мне бы точно по глазам резанул case после default
иногда это удобно, когда есть некий case 'X', который нужно выполнить не только в случае X, но и в случае default тоже. Причём в случае default надо ещё что-то выполнить.
14.01.2015 07:54 #409533

"voral" написал:
Не, ну если предположить совсем быдлокод
на самом деле, надо понимать, зачем вообще появилось switch/case.

Эта конструкция избыточна, и может быть отменена. Т.е. она необязательна, без неё можно обойтись, заменив её хотя-бы if/else.

Однако, почти в любом процессоре есть косвенный jump, т.е. не просто
text
jump куда_то

а

text
jump [таблица+индекс]

т.е. мы подготавливаем таблицу переходов, и потом одной командой прыгаем на нужный вариант. Это естественно на порядок быстрее, чем перебирать разные альтернативы.

Goto умеет прыгать только на фиксированную метку, и что-бы в C сделать такой косвенный переход по таблице, K&R придумали switch/case. Т.к. управляющая переменная является индексом, она может быть только целой.

В C++ тоже есть свой косвенный переход, в виртуальных функциях, причём он дважды косвенный: у каждого объекта в C++ имеется (в общем случае) указатель на Virtual Table, а эта VT представляет собой таблицу переходов виртуальных методов. Т.е. что-бы выполнить виртуальный метод для объекта, нам нужно:

1. разименовать указатель на VT объекта

2. перейти по адресу указанному в VT+смещение конкретного метода.

В C++ предпочтительнее использовать виртуальные методы, нежели switch/case. Но в простых случаях это слишком накладно.

PS: естественно оптимизирующий компилятор вовсе не обязательно будет обрабатывать switch/case описанным образом, он сделает так, как быстрее в данном конкретном случае.

14.01.2015 08:16 #409534
"drBatty" написал:
иногда это удобно, когда есть некий case 'X', который нужно выполнить не только в случае X, но и в случае default тоже. Причём в случае default надо ещё что-то выполнить.

Я об этом тоже подумал... И, даже, случалось применять (правда не с default, а с другим case). Но, в этих случаях всегда не дает покоя "а вдруг, кто-то из команды, или сам с будуна, через пару лет воткнем между ними еще один case. Понятно, что такие моменты надо коментить, но тем не менее. Да и вообще, может таки лучше четко разделять, а нужный код объединять темиже функциями...... Тут может, конечно, без конкретного проекта решать не имеет смысла для "вообще". но.....

14.01.2015 09:07 #409536

voral, ну надо просто помнить, что switch это замаскированное goto, и быть готовым к НЕОЖИДАННЫМ эффектам.

ИМХО основная ошибка ТСа в том, что он очень сложную логику запихал в switch. Я-бы сделал так:

text
switch(c)
{
  case 1:
    do_menu1();
    break;
  case 2:
    do_menu2();
    break;
  …
  default:
    // неверный ввод
    …
    break/return/_exit(1);
}
Войдите или зарегистрируйтесь, чтобы ответить.