Home > Software engineering >  How is exit not working ? Login and Registration system in C
How is exit not working ? Login and Registration system in C

Time:11-17

I'm a beginner and I'm trying to make a console login, registration and forgot password. The code simply works and it looks like this..

How the output looks like

Problem:
Every thing works fine and when I select 3 it goes inside forgot password just like it should

How forgot password looks like

And when I select 2 it goes back.

How the output looks like

And after doing the above steps, when I select 4 to exit, it goes back inside forgot password and runs the default of the switch statement inside the forgotPassword() function. ( That's why it says invalid number 2 at the top in the screenshot below. )

Runs forgot password again

I really don't know why but it runs forgot password again, but when I press other keys it works fine.

Source Code:

#include <iostream>
#include <fstream>

using namespace std;

// call functions
void login();
void registration();
void forgotPassword();

int main()
{
    int choice;

    cout << "-------------- WELCOME --------------\n";
    cout << "::Select Action::\n\n";

    cout << "1. Login\n";
    cout << "2. Register\n";
    cout << "3. Forgot Password\n";
    cout << "4. Exit\n\n";

    cout << "Enter your choice: ";
    cin >> choice;

    cout << endl;


    //handle choice
    switch (choice) {
        case 1:
            login();
            break;

        case 2:
            registration();
            break;

        case 3:
            system("cls");
            forgotPassword();
            break;

        case 4:
            system("cls");
            cout << "Thank you for using this app." << endl;
            break;

        default:
            system("cls");
            cout << "-- Invalid number " << choice << " --" << endl;
            main();
    }
    return 0;
}

//login function
void login() {
    int count = 0;
    string userId, password, id, pass;

    system("cls");

    cout << "::Enter the username and password::\n\n" << endl;

    cout << "Username: ";
    cin >> userId;

    cout << "Password: ";
    cin >> password;

    ifstream input("users.txt");

    while (input >> id >> pass) {
        if (id == userId && pass == password) {
            count = 1;
            system("cls");
        }
    }

    input.close();

    if (count == 1) {
        cout << "Login Successful!\n\n" << userId << endl;
        main();
    }
    else {
        cout << "\n-- Username or password is invalid. --" << endl;
    }
}

//register function
void registration() {
    string userId, password, id, pass;
    system("cls");

    cout << "::Enter the username and password::\n\n" << endl;

    cout << "Username: ";
    cin >> userId;

    cout << "Password: ";
    cin >> password;

    ofstream newUser("users.txt", ios::app);

    newUser << userId << ' ' << password << endl;
    system("cls");

    cout << "-- Registration Successful! --\n\n" << endl;
    main();
}

//forgot password function
void forgotPassword() {
    int option;
    
    cout << "::Forgot Password::\n\n" << endl;

    cout << "1. Search by username" << endl;
    cout << "2. Go Back\n" << endl;
    
    cout << "Select option: ";
    cin >> option;
    

    switch (option) {
    case 1 : {
        int count = 0;
        string userId, password, id, pass;

        cout << "Enter your username: ";
        cin >> userId;

        ifstream users("users.txt");

        while (users >> id >> pass) {
            if (id == userId) {
                count = 1;
            }
        }

        users.close();

        if (count == 1) {
            system("cls");
            cout << "-- User Found --\n" << endl;
            cout << "Username: " << userId << endl;
            cout << "Password: " << pass << endl;
        }
        else {
            system("cls");
            cout << "Account doesn't exist!\n" << endl;
            main();
        }

        break;
    }

    case 2: {
        system("cls");
        main();
    }

    default:
        system("cls");
        cout << "-- Invalid number " << option << " --" << endl;
        forgotPassword();
    }
}

CodePudding user response:

Line 151 (and others):

        else {
            system("cls");
            cout << "Account doesn't exist!\n" << endl;
           main(); // Don't do this
        }

You want to return here, not call main() - which is undefined behaviour as the comments already pointed out and is forbidden by the standart, see here for more.

If you want to return to the top of your primary switch (choice) after a function call, consider wrapping it in a loop of choice.

CodePudding user response:

While it may seem like using recursion (i.e calling main inside of it to create a loop) may seem like a good idea, as @463035818_is_not_a_number says, calling main from inside the program is forbidden in c and yields undefined behavior. The C 14 standard states in [3.6.1] that:

3 The function main shall not be used within a program.

Essentially you can change your recursion by using a loop with a flag to control the loop and in the option to stop the program change the flag to false so that it exits the loop and returns.

Then, we would change main to this

int main()
{
    bool continue_program = true;
    while (continue_program)
    {

        int choice;

        cout << "-------------- WELCOME --------------\n";
        cout << "::Select Action::\n\n";

        cout << "1. Login\n";
        cout << "2. Register\n";
        cout << "3. Forgot Password\n";
        cout << "4. Exit\n\n";

        cout << "Enter your choice: ";
        cin >> choice;

        cout << endl;

        // handle choice
        switch (choice)
        {
        case 1:
            login();
            break;

        case 2:
            registration();
            break;

        case 3:
            system("cls");
            forgotPassword();
            break;

        case 4:
            system("cls");
            cout << "Thank you for using this app." << endl;
            continue_program = false;
            break;

        default:
            system("cls");
            cout << "-- Invalid number " << choice << " --" << endl;
        }
    }
    return 0;
}

You should also change your calls to main from other functions to return as it will make them return to the main function where they left, now that we have the loop they will just loop again into the options print.

This would be the complete program with the calls to main changed to return and the loop added

#include <iostream>
#include <fstream>

using namespace std;

// call functions
void login();
void registration();
void forgotPassword();

int main()
{
    bool continue_program = true;
    while (continue_program)
    {

        int choice;

        cout << "-------------- WELCOME --------------\n";
        cout << "::Select Action::\n\n";

        cout << "1. Login\n";
        cout << "2. Register\n";
        cout << "3. Forgot Password\n";
        cout << "4. Exit\n\n";

        cout << "Enter your choice: ";
        cin >> choice;

        cout << endl;

        // handle choice
        switch (choice)
        {
        case 1:
            login();
            break;

        case 2:
            registration();
            break;

        case 3:
            system("cls");
            forgotPassword();
            break;

        case 4:
            system("cls");
            cout << "Thank you for using this app." << endl;
            continue_program = false;
            break;

        default:
            system("cls");
            cout << "-- Invalid number " << choice << " --" << endl;
        }
    }
    return 0;
}

// login function
void login()
{
    int count = 0;
    string userId, password, id, pass;

    system("cls");

    cout << "::Enter the username and password::\n\n"
         << endl;

    cout << "Username: ";
    cin >> userId;

    cout << "Password: ";
    cin >> password;

    ifstream input("users.txt");

    while (input >> id >> pass)
    {
        if (id == userId && pass == password)
        {
            count = 1;
            system("cls");
        }
    }

    input.close();

    if (count == 1)
    {
        cout << "Login Successful!\n\n"
             << userId << endl;
        return;
    }
    else
    {
        cout << "\n-- Username or password is invalid. --" << endl;
    }
}

// register function
void registration()
{
    string userId, password, id, pass;
    system("cls");

    cout << "::Enter the username and password::\n\n"
         << endl;

    cout << "Username: ";
    cin >> userId;

    cout << "Password: ";
    cin >> password;

    ofstream newUser("users.txt", ios::app);

    newUser << userId << ' ' << password << endl;
    system("cls");

    cout << "-- Registration Successful! --\n\n"
         << endl;
    return;
}

// forgot password function
void forgotPassword()
{
    int option;

    cout << "::Forgot Password::\n\n"
         << endl;

    cout << "1. Search by username" << endl;
    cout << "2. Go Back\n"
         << endl;

    cout << "Select option: ";
    cin >> option;

    switch (option)
    {
    case 1:
    {
        int count = 0;
        string userId, password, id, pass;

        cout << "Enter your username: ";
        cin >> userId;

        ifstream users("users.txt");

        while (users >> id >> pass)
        {
            if (id == userId)
            {
                count = 1;
            }
        }

        users.close();

        if (count == 1)
        {
            system("cls");
            cout << "-- User Found --\n"
                 << endl;
            cout << "Username: " << userId << endl;
            cout << "Password: " << pass << endl;
        }
        else
        {
            system("cls");
            cout << "Account doesn't exist!\n"
                 << endl;
            return;
        }

        break;
    }

    case 2:
    {
        system("cls");
        return;
    }

    default:
        system("cls");
        cout << "-- Invalid number " << option << " --" << endl;
        forgotPassword();
    }
}
  •  Tags:  
  • c
  • Related