Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 1
Регистрация: 03.08.2014
Сообщений: 49
1

Рекурсия (вызов только 3 раза)

04.03.2015, 15:03. Показов 1589. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет! Есть программка, проблема заключается в том чтобы сделать вызов рекурсии ТОЛЬКО 3 раза, т.е. как при пароле, есть только 3 попытки. Сейчас она вызывается постоянно, если введено неверное значение. Как сделать вызов только 3 раза...
C++
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
#include <iostream>
#include <string>
#include <windows.h>
 
using namespace std;
 
bool password_is_valid(string password)
{
    string valid_pass = "qwerty123";
    if (valid_pass == password)
        return true;
    else
        return false;
}
 
void get_pass()
{
    string user_pass;
    cout << "Введите пароль: ";
    getline(cin, user_pass);
    if (!password_is_valid(user_pass)) {
        cout << "Неверный пароль!" << endl;
        get_pass();
    }
    else {
        cout << "Доступ разрешен." << endl;
    }
}
 
int main()
{   
    setlocale(0, "rus");
    get_pass();
    system("pause");
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.03.2015, 15:03
Ответы с готовыми решениями:

Рекурсия: как выделяется память под рекурсивный вызов?
на картинке файлик из википедии в которой говорится что рекусия имеет вид дерева и некоторые ветви...

Очень странная ошибка: Функция gets() вызывается только со второго раза
Нужно написать класс, в объект которого (в массив строк) вводятся несколько фамилий Для записи...

Рекурсия: как выводить на экран только удовлетворяющие условия
Всем привет. Есть код: #include &lt;iostream&gt; using namespace std; int values = {0}; int...

Найти максимальное число, встречающееся в заданном массиве только два раза
Найти максимальное число, встречающееся в заданном массиве только два раза. Заранее спасибо!!

16
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.03.2015, 15:12 2
Добавить переменную счетчика попыток вестимо.
Например так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void get_pass()
{
    static int tryCnt = 0;
    if( ++tryCnt >= 3 )
    {
        cout << "Попытки кончились." << endl;
        return;
    }
    string user_pass;
    cout << "Введите пароль: ";
    getline(cin, user_pass);
    if (!password_is_valid(user_pass)) {
        cout << "Неверный пароль!" << endl;
        get_pass();
    }
    else {
        cout << "Доступ разрешен." << endl;
        tryCnt = 0;
    }
}
1
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
04.03.2015, 15:17 3
Маша - это Маша, но 3 раза - это 3 раза! (С)
Заводите интовый параметр в вашу гет пасс, каждый вложенный вызов осуществляете с увеличением его на единицу, в начале функции проверяете его значение, первый вызов в мэйне делаете с нулевым или единичным значением - все.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void get_pass(int tryes)
{
    string user_pass;
    if (tryes>3) cout << "Сколько можно ошибаться! Не дам доступ :)";
    else {
        cout << "Введите пароль: ";
        getline(cin, user_pass);
        if (!password_is_valid(user_pass)) {
            cout << "Неверный пароль!" << endl;
            get_pass(tryes + 1);
        }
        else {
            cout << "Доступ разрешен." << endl;
        }
    }
}
 
int main()
{   
    setlocale(0, "rus");
    get_pass(1);
    system("pause");
    return 0;
}
Добавлено через 2 минуты
Tulosba, не видел ваш вариант когда писал свой. Статик... Имхо, явный аргумент по значению тут элегантнее смотрится.
1
0 / 0 / 1
Регистрация: 03.08.2014
Сообщений: 49
04.03.2015, 15:18  [ТС] 4
Спасибо!)
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.03.2015, 15:24 5
Цитата Сообщение от _Ivana Посмотреть сообщение
Статик... Имхо, явный аргумент по значению тут элегантнее смотрится.
Статические переменные в функциях это вообще не оч.хорошо. При условии использования ООП они должны переехать в поля класса. Но т.к. тут никакого ООП по сути нет, я предложил самое простое (как мне показалось) решение. Инкапсуляция переменной внутри метода (static), имхо в данном случае проще, чем передача аргумента, т.к. вся логика остается внутри метода (параметр при вызове не нужен). Также не меняется сигнатура функции get_pass().
1
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
04.03.2015, 15:30 6
Tulosba, все понимаю, кроме одного А сейчас нет под рукой компилятора чтобы проверить. Если бы вы просто сделали честную глобальную переменную и зануляли ее ДО вызова гет_пасс в мэйне, а внутри гет_пасс только инкрементировали и проверяли ее значение, но не зануляли, тогда было бы все железно и понятно. А сейчас у вас она статик, то есть по сути глобальная, но видна только из гет_пасс, а вы кажый раз ее там зануляете - с какого она должна быть больше единицы при очередном вызове? Или объясните где я ошибаюсь, или скажите что я прав
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.03.2015, 15:33 7
Цитата Сообщение от _Ivana Посмотреть сообщение
кажый раз ее там зануляете
Не каждый, а только при удачном вводе пароля.
Цитата Сообщение от _Ivana Посмотреть сообщение
А сейчас нет под рукой компилятора чтобы проверить.
ideone.com // и куча других в помощь
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
04.03.2015, 15:41 8
Хм... Оказывается (внезапно), что при последующих рекурсивных вызовах статическая переменная не переопределяется если она уже была определена и ей было назначено значение при определении в первом вызове.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
 
void get_pass()
{
    static int tryCnt = 0;
    cout << "Попытка № " << tryCnt << endl;
    if( ++tryCnt >= 3 )
    {
        cout << "Попытки кончились." << endl;
        return;
    }
    get_pass();
}
 
int main() {
    get_pass();
    get_pass();
    return 0;
}
http://ideone.com/vhQDJz
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.03.2015, 15:47 9
Цитата Сообщение от _Ivana Посмотреть сообщение
Оказывается (внезапно)
Это же базовые вещи Статическая переменная внутри функции инициализируется только 1 раз. Иначе она была бы обычной локальной.
0
4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28
04.03.2015, 15:50 10
Хотя действительно, что это я... При тех же циклических (а не рекурсивных) вызовах функции статические переменные именно так себя и ведут, просто меня запутала рекурсивная вложенность контекстов, а статики (как глобальные по сути) ничем в данном случае не отличаются по своему поведению. Но в любом случае спасибо за науку

ЗЫ а про базовые вещи... Вот когда писал на одном языке, знал его повадки, приоритеты операций, передачу параметров по значению/ссылке и т.п. А когда попробовал другие - уже начинаю иногда путаться где у чего какая область видимости и т.п. Так что звиняйте барин за проколы в базовых вещах
0
Tulosba
04.03.2015, 16:04
  #11

Не по теме:

Цитата Сообщение от _Ivana Посмотреть сообщение
звиняйте барин за проколы в базовых вещах
Со всеми случается время от времени. :handshake:

0
0 / 0 / 1
Регистрация: 03.08.2014
Сообщений: 49
04.03.2015, 16:35  [ТС] 12
Вопрос, а как этот код правильно перевести для СИшки?
C++
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
bool password_is_valid(string password)
{
    string valid_pass = "qwerty123";
    if (valid_pass == password)
        return true;
    else
        return false;
}
 
void get_pass()
{
    static int tryCnt = 0;
    if (++tryCnt > 3)
    {
        cout << "\n >  Доступ запрещён!\n" << endl;
        return;
    }
    string user_pass;
    cout << "Введите пароль: ";
    getline(cin, user_pass);
    if (!password_is_valid(user_pass)) {
        cout << "Неверный пароль!" << endl;
        get_pass();
    }
    else {
        cout << "\n >  Доступ разрешен!\n" << endl;
        tryCnt = 0;
        system("cls");
    }
}
По большей части интересует getline и string.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.03.2015, 16:53 13
Цитата Сообщение от AlexLag Посмотреть сообщение
getline и string.
scanf() и char*
1
0 / 0 / 1
Регистрация: 03.08.2014
Сообщений: 49
04.03.2015, 17:01  [ТС] 14
Цитата Сообщение от Tulosba Посмотреть сообщение
scanf() и char*
А эту строчку? getline(cin, user_pass);
scanf(user_pass); ??

C
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
#include <string.h>
#include <stdio.h>
#include <windows.h>
 
bool password_is_valid(char* password)
{
    char* valid_pass = "qwerty123";
    if (valid_pass == password)
        return true;
    else
        return false;
}
 
void get_pass()
{
    static int tryCnt = 0;
    if (++tryCnt > 3)
    {
        printf("\n >  Доступ запрещён!\n");
        return;
    }
    char* user_pass;
    printf("Введите пароль: ");
    scanf(user_pass);
    if (!password_is_valid(user_pass)) {
        printf("Неверный пароль!");
        get_pass();
    }
    else {
        printf("\n >  Доступ разрешен!\n");
        tryCnt = 0;
        system("cls");
    }
}
 
int main()
{
    setlocale(0, "rus");
    printf("У вас есть 3 попытки! Помните об этом.");
    get_pass();
    printf("Continue...");
    system("pause");
    return 0;
}
Ошибки:
Кликните здесь для просмотра всего текста

Ошибка 1 error C2061: синтаксическая ошибка: идентификатор "password_is_valid"
Ошибка 2 error C2059: синтаксическая ошибка: ;
Ошибка 3 error C2059: синтаксическая ошибка: тип
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.03.2015, 17:05 15
AlexLag, не всё так просто как хотелось бы
На самом деле для чтения строки (чтоб с пробелами) в сях стоит использовать скорее gets, а не scanf.
Давно на сях не писал, уже подзабыл.
0
0 / 0 / 1
Регистрация: 03.08.2014
Сообщений: 49
04.03.2015, 17:09  [ТС] 16
Цитата Сообщение от Tulosba Посмотреть сообщение
AlexLag, не всё так просто как хотелось бы
На самом деле для чтения строки (чтоб с пробелами) в сях стоит использовать скорее gets, а не scanf.
Давно на сях не писал, уже подзабыл.
Ок, буду пробовать...Правда проблема с булом...
Кликните здесь для просмотра всего текста
Ошибка 1 error C2061: синтаксическая ошибка: идентификатор "password_is_valid"
Ошибка 2 error C2059: синтаксическая ошибка: ;
Ошибка 3 error C2059: синтаксическая ошибка: тип
6 IntelliSense: идентификатор "bool" не определен
7 IntelliSense: идентификатор "true" не определен
8 IntelliSense: идентификатор "false" не определен
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.03.2015, 17:13 17
Цитата Сообщение от AlexLag Посмотреть сообщение
Правда проблема с булом...
C
1
#include <stdbool.h>
0
04.03.2015, 17:13
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2015, 17:13
Помогаю со студенческими работами здесь

Рекурсия: умножение двух чисел, используя только операцию сложения
Помогите ребята.На языке (с++) Написать функцию умножения двух чисел, используя только операцию...

Рекурсия: вычисление произведения элементов массива (только четных и больше 0)
Задание : С++ Написать рекурсивную функцию вычисления произведения элементов массива только четных...

Cкопировать в массив только те элементы, который в первом массиве встретились ровно 2 раза
Программа должна создавать динамический массив из 20 случайных элементов их диапазона и вывести...

Рекурсия: функция умножения двух чисел, используя только операцию сложения
Напишите функцию умножения двух чисел, используя только операцию сложения(через рекурсию)


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru