#include <iostream>
#include <fstream>
#include <windows.h>
#include <iomanip>
using namespace std;

void printMainPage();   //customer need to register 1st Page
void printUserPage();   //User(registered customer) page
void Login();
bool openFileIn(fstream &, string );
//fstream in_file("Register and Login Details.txt");
fstream file("Register and Login Details.txt", ios::out | ios::in);

int main()
{
    printMainPage();

    system("cls");
    printUserPage();

    return 0;
}

void printMainPage()    //Main page
{
    int choiceMainPage,
        usercount=0;    //userCount

    static int userReg=0;       //howmuch have register

    string reg_pwd,     //password
           reg_name;    //username

    cout<<"********WELCOME TO MEK DINAH**********\n\n";
    cout<<"\t1. Register \n";
    cout<<"\t2. Login \n";
    cout<<"\t3. Exit program.\n";
    cout<<"\n\n\t\t Registered User : " << userReg;
    cout<<endl;
    cout<<"\n**************************************\n";

    cout << "Your choice: ";
    cin>>choiceMainPage;
        while(choiceMainPage<1 || choiceMainPage>3)      
        {
            cout << "Invalid, re-enter again: ";
            cin >> choiceMainPage;
        }

    if(choiceMainPage==1)   //Register
    {
        system("cls");

        cout << "Please key-in your information" << endl;
        cin.ignore();

        cout<<"Username : ";
        getline(cin,reg_name);
        cout<<endl;

        cout<<"Password : ";
        getline(cin,reg_pwd);
        cout<<endl;

        cout << "Username: " << reg_name << "\npassword: " << reg_pwd << endl;
        file << reg_name << "#" << reg_pwd << "#";

        userReg++;

        cout << "You will be brought back to our main page...\nPlease wait";

        Sleep (3000);
        system("cls");

        printMainPage();
    }

    else if(choiceMainPage==2) //login
    Login();

    else //exit
    exit(0);

file.close();           
}


void Login()
{
    char login_un[50],
         login_pw[50], 
         username[10][50], 
         password[10][50];   //nanti tarik dpd fail

    int choiceLogin,
        conditionLogin;

    cout<<"Main\n\n"
        <<"1.Login\n"
        <<"2.Main Page\n";
    cin>> choiceLogin;
        while(choiceLogin<1 || choiceLogin>2)
        {
            cout << "Invalid, re-enter again: ";
            cin >> choiceLogin; 
        }

    if (choiceLogin==1)
    {
        int userCount=0;
        if(openFileIn(file, "Register and Login Details.txt"))
        {
            while(file)
            {
                file.getline(username[userCount], 50, '#'); //read existing username 
                file.getline(password[userCount], 50, '#'); //read existing passowrd

            userCount++;
            }
        }
        cout << "checking existing data" << endl;
        Sleep(1000);
        for(int x=0; x<userCount; x++)
        cout << "username: " << username[x] << "\npassword: " << password[x] << endl;


        do
        {
            cin.ignore();

            cout<<"Username: ";
            cin.getline(login_un, 50);

            cout<<endl;

            cout<<"Password: ";
            cin.getline(login_pw, 50);

            for(int x=0; x<userCount; x++)
            {
                if (strcmp(login_un, username[x])==0)
                {
                    if(strcmp(login_pw, password[x])==0) //comparing both username n password
                    {
                        conditionLogin=0;
                        break;
                    }


                }
                cout << "x : " << x << " UserCount: " << userCount << endl;
            }

            cout << "Username and password doesn't match, Please reenter again:" << endl;
            conditionLogin=1;       //if 1 then loop again
            cin.ignore();
        }while(conditionLogin==1);      
    }

    else
    {
        printMainPage();
    }
    return;

file.close();   
}

void printUserPage()    //User Page
{
    cout<<"********WELCOME TO MEK DINAH**********\n\n";
    cout<<"\t1. Displaying Menu \n";
    cout<<"\t4. Order \n";
    cout<<"\t5. Display Receipt\n";
    cout<<"\t3. Exit to Main page.\n";
    cout<<endl;
    cout<<"\n**************************************\n";



}

bool openFileIn(fstream &in_file, string name)
{
    in_file.open(name.c_str(), ios::in);
    if(in_file.fail())
        return false;
    else
        return true;
}

What is openFileIn(file, "Register and Login Details.txt") returning? Are you actually getting into the loop? Where is the file located that you are trying to read? If you are not fully qualifying your name then it needs to either be where your source files are or in the same location as the .exe file.

yes, yes of course i put it in the same folder. The openFileIn function is to check whether the file exist or not.
And it is a bool function type. Return true and false. But the problem here is that at the line 113, the variables aren't passed to it. That's what i've been trying to figure it out.

Are you sure it is opening the file? Put a cout statement between lines 112 and 113 and see if it prints the stament. This will let you now if the file was opened succesfully. It should work if the file is being opened. What does the file look like?

I've tried. And yes, it does not even enter that line. Do you know of how i can fix this sir? i've been trying to fix it since 2 days ago.

You could try using ifstream for file input, and ofstream for file output.
Also, I would suggest using a map for storing(in memory) your users and their respective passwords.
Another thing, try using strings instead of char array. They are more reliable, and you can do much more with them.
Using iostream's getline will suite you better, if using strings, when reading from files.

Here's a minimalist example:

#include <iostream>
#include <string>
#include <map>
#include <fstream>
using namespace std;

int main(){
    static const string filename = "a.txt";
    map<string, string> users;
    ifstream fin (filename.c_str(), ios::in);
    if (fin.good()){ //checks if the file exists
        string temp_usr, temp_pas;
        while (getline(fin, temp_usr, '#')){ //gets the user
            getline(fin, temp_pas, '#'); //gets the password
            users[temp_usr] = temp_pas; //stores them in the map
        }
        while (true){ //now let's check the users
            cout<<"Username: ";
            cin>>temp_usr;
            cout<<"Password: ";
            cin>>temp_pas;
            if (users.count(temp_usr) > 0 && users.find(temp_usr)->second == temp_pas) {
                cout<<"Welcome: "<<temp_usr<<endl;
                break;
            }
            else cout<<"Invalid creditials.\n";
        }
    }
    return 0;
}

having a file called a.txt that looks like this:

aladdin#ala#
solis#sol#

Edited 3 Years Ago by Lucaci Andrew

Lucaci's suggestions are good. I have some additional comments.

If you want to understand why your original/existing code is failing:
Part of your problem is that you are using a single, global stream to deal with file I/O. Another, bigger part of the problem is that you are not closing the files in appropriate places before attempting to open the file again.

Also, when you initialise your global fstream, you are naively assuming that it opened successfully. And in this case, you got lucky, because the file was opening. But because you failed to close the file before attempting to reopen it in read mode in your login code, your openFileIn function was failing!

To prove this, take another look at your code:
When printMainPage is first called in main, the file is already open (or at least it might be... See above!).

If the user selects '1' to register, you are naively assuming that the global fstream object will be open and are then writing to the file.. Which is bad because there is no guarantee that the file opened successfully in the first place. Also, more importantly another mistake you've made is that you are not closing the file until right at the very end of the function.... And I could be wrong, but from looking at your code I don't think the file will ever get closed with the call to close there. That particular area of the code looks unreachable!

To compound things:
If the user selected '2' to login and the login function is called; By the time we hit this point, the file was not closed, so assuming the file opened successfully when the global fstream object was declared; the global fstream object still has the file open.

So then on the next page, the user selects '1' to login; which is when your openFileIn function is called. By this point I am certain that the call to openFileIn is failing because the global fstream object still has the file open. So attempting to get the fstream to open the file, when it already has it open will cause the call to open to fail, so openFileIn will return false.

Hopefully that sheds some light on your problem and why it is happening.

So, now we know what the problem is; how do we fix it?
Well, from looking at your code you only have two places where the files are being used. In your register user code and your login code. So if you declare local fstream objects where they are actually used rather than declaring a single, global instance it will make things a little easier for you. Also you should only open the file immediately before you are going to use it and should close it immediately afterwards. Don't leave files open for longer than they need to be. As soon as the file is done with, close it!

You could make the filename a global const string, but I really don't think the fstream object should be global. Again, declare local fstream objects where and when you need to use them (or you could use ifstream and ofstream as suggested by Lucaci).

To give you an idea of what I mean by closing files as soon as they are done with, here's what I think your register code should be doing (in pseudo-code - not real code! I'll leave you to write that!):

if(userchoice == register)
{
    open the file in read mode (NOTE: Declare a local fstream or ifstream object!)
    if (file opened)
    {
        read usernames from file 
        close file
        Get the new username and password from the user
        check username doesn't already exist
        if (username doesn't exist)
        {
            reopen file for write/append 
            {NOTE: reuse the local fstream object to reopen the file, 
            or use an ofstream object if you used an ifstream to read...entirely up to you!}
            if(file opened)
            {
                append new username and password to the end of the file
                close file
            }
            else
                ERROR: Failed to open file for write
        }
        else
            ERROR: username already exists
    }
    else
        ERROR: Failed to open file for read
}

That way your file usage is contained neatly and tightly and you should be able to avoid a lot of silly problems!
You might want to do something different to check whether a user already exists in the system, I can think of several different ways, the above is merely a suggestion!

You should do something similar for your login code. Again, I'll leave you to work that out!

Things to remember:

  1. Try to avoid using global variables as far as possible. Globals should really only be used for system-wide constants (like perhaps your file-name). All other variables should be given appropriate scope by being declared where they are used!

  2. Try to keep your file-handling code together, open the files where needed and ensure they are closed as soon as you have finished with them!

All the best!

Edited 3 Years Ago by JasonHippy

Thank You both of you sir. These two codes seem good. I'll try first. My project is actually not only this login and register system. It is about online-ordering service just like Pizza Hut, Mc'Donald and etc.Lets try the codes first. Thank you.

This article has been dead for over six months. Start a new discussion instead.