Vlad George
Vlad George

Reputation: 43

Can one clear a variable in a recursive function?

I'm trying to build a program in which it takes your name and surname as input (so far) and passes it on to upcoming functions. Now I'm trying to do something with resetting the variable in a recursive function because I thought of the following scenario: if someone somehow messes up writing their name/surname I want to give them a chance to write it again... but the program doesn't delete the "bad" data and keeps it no matter how many times the user messes up writing their name. This is the code so far:

#include <iostream>

using namespace std;

string name_data()
{
    string name;
    string surname;

    cout<<"Welcome to CV/resume creator. Please enter your surname: "<<endl;
    cin>>surname;

    cout<<endl<<"Now please enter your name: "<<endl;
    cin>>name;

    bool false_characters=false;
    string unallowed="!@#$%^&*()1234567890";

    for(int i=0; i<unallowed.size(); i++){
        for(int j=0; j<surname.size(); j++){
            if(unallowed[i]==surname[j]){
                cout<<"Sorry, your surname cannot possibly contain those characters in it (unless you're Elon Musk's heir).\nReturning to beginning..."<<endl;
                false_characters=true;
                name_data();
            }
        }
        for(int k=0; k<name.size(); k++){
            if(unallowed[i]==name[k]){
                cout<<"Sorry, your name cannot possibly contain those characters in it (unless you're Elon Musk's heir).\nReturning to beginning..."<<endl;
                false_characters=true;
                name_data();
            }
        }
    }

    string confirmation;
    if(false_characters!=true){
        cout<<endl<<"Your name is "+surname+" "+name+". Is that correct?"<<endl;
        cin>>confirmation;
        if(confirmation=="no"){
            cout<<"Back to beginning..."<<endl<<endl;
            surname.clear();
            name.clear();
            name_data();
        }
    }
    string full_name=surname+" "+name;
    return full_name;
}

int main()
{
    cout<<name_data();
    return 0;
}

Upvotes: 2

Views: 989

Answers (3)

asmmo
asmmo

Reputation: 7100

When you need to correct the data, you call name_data();, hence it executes and then comes back to the scope where the data is bad. Instead, you need to make the scope where the data is bad return the data in the new scope, so do as follows. make it return not only call

if(confirmation=="no"){
   cout<<"Back to beginning..."<<endl<<endl;
   return name_data();
}

Note that you have independent data in each call stack you make, hence you don't need clear().

It's better to change the recursion style to something like

bool repeatCond = true;

while(repeatCond){
    //your body
    //ask the user if this is satisfying and change the condition

}

to avoid the cost of the data and the cost of recurrsion.

Upvotes: 3

Vlad George
Vlad George

Reputation: 43

Thank you guys a lot for your solutions. I corrected it now with your hints and advices and it is working as I wanted. Here is the modified code for who is interested:

#include <iostream>

using namespace std;

string name_data()
{
    string name;
    string surname;

    cout<<"Welcome to CV/resume creator. Please enter your surname: "<<endl;
    cin>>surname;

    cout<<endl<<"Now please enter your name: "<<endl;
    cin>>name;

    bool false_characters=false;
    string unallowed="!@#$%^&*()1234567890";

    for(int i=0; i<unallowed.size(); i++){
        for(int j=0; j<surname.size(); j++){
            if(unallowed[i]==surname[j]){
                cout<<"Sorry, your surname cannot possibly contain those characters in it (unless you're Elon Musk's heir).\nReturning to beginning..."<<endl;
                false_characters=true;
                return name_data();
            }
        }
        for(int k=0; k<name.size(); k++){
            if(unallowed[i]==name[k]){
                cout<<"Sorry, your name cannot possibly contain those characters in it (unless you're Elon Musk's heir).\nReturning to beginning..."<<endl;
                false_characters=true;
                return name_data();
            }
        }
    }

    string confirmation;
    if(false_characters!=true){
        cout<<endl<<"Your name is "+surname+" "+name+". Is that correct?"<<endl;
        cin>>confirmation;
        if(confirmation=="no"){
            cout<<"Back to beginning..."<<endl<<endl;
            return name_data();
        }
    }
    string full_name=surname+" "+name;
    return full_name;
}

int main()
{
    cout<<name_data();
    return 0;
}

Upvotes: 1

Melebius
Melebius

Reputation: 6695

You have declared name and surname local variables in your function. When you call the function again, another copy of these variables is created. To use values collected in a recursive call, you’d have to return them and store them in the calling code but your recursive call statements

name_data();

drop the returned value. You could:

  • either keep the data returned from the recursive calls and use them instead of the original ones (e.g. return name_data();),
  • or rewrite your function to use a cycle instead of recursion.

Upvotes: 2

Related Questions