I have a few sets of username and password in the file but when I try to login, the program could only read the first set of username and password. The rest will be invalid input eventhough I key in correctly.

#ifndef USERLOG_H
#define USERLOG_H

class UserLog
{
public:
    char newUserName[25];
    char userName[25];
    char newPassword[16];
    char password[16];

    void createUser();
    void checkUser();
};

#endif



#include<iostream>
#include<fstream>
#include<string>
#include "userLog.h"

using namespace std;

string temp;
string temp1;

ofstream editUserLog("User Log.txt", ios::app); 
ifstream readUserLog("User Log.txt"); 

void UserLog::createUser()
{
    if(editUserLog.is_open())
    {
        cout << "Enter desired username: ";
        cin >> newUserName;
        editUserLog << newUserName << endl;

        cout << "\nEnter desired password: ";
        cin >> newPassword;
        editUserLog << newPassword << endl;

        editUserLog.close();
    }
}

void UserLog::checkUser()
{
    if(readUserLog.is_open())
    {
        cout << "Enter your username: ";
        cin >> userName;
        cout << "\nEnter your password: ";
        cin >> password;

        readUserLog >> temp;
        readUserLog >> temp1;

        if(userName == temp && password == temp1)
        {
            cout << "\nWelcome " << userName << endl;
        }   
        else
            cout << "\nInvalid username or password." << endl;

        readUserLog.close();
    }

}



#include<iostream>
#include<fstream>
#include "userLog.h"

using namespace std;

int main()
{
    UserLog ul;
    char choice;

    while(1)
    {
        cout << "Welcome to the Student Grade Management System" << endl;
        cout << "What would you like to do?\n" 
            << "[C] Create User\n"
            << "[L] Login\n"      
            << "[Q] Quit\n";
        cin >> choice;

        if(choice == 'c' || choice == 'C')
        {
            ul.createUser();
        }
        else if(choice =='l' || choice == 'L')
        {
            ul.checkUser();
        }
        else if(choice == 'q' || choice == 'Q')
        {
            break;
        }
        else
        {
            cout << "Invalid Input" << endl;
            continue;
        }
    }

    cout << "Have a nice day" << endl;

    system("PAUSE");

    return 0;
}

As you are using classes, why don't you use

UserLog newUser ;

fin.write( (char*) &newUser, sizeof(newUser)); // writing user info to file

fin.read( (char*) &newUser, sizeof(newUser));  // reading user info from file

Then you define a getter function which returns the password of the current object, and you can check it with the given password.

You only read the file once and you're done. What do you need to read more than one record?

There is no need to read more than one record. My situation is that the program only successfully read one username and password in the file.

For example, below is the data in the file.

admin1
password1
admin2
password2
admin3
password3

When I try to log in, it only accept admin1 as username and password1 as password.. If I try to log in using admin2, the program will return 'Invalid username or password.' instead of the welcome.

As you are using classes, why don't you use
UserLog newUser ;
fin.write( (char) &newUser, sizeof(newUser)); // writing user info to file
fin.read( (char
) &newUser, sizeof(newUser)); // reading user info from file
Then you define a getter function which returns the password of the current object, and you can check it with the given password.

I'm sorry, I am still new to C++ so there are many things which I am not so sure about. May I know where am I suppose to put the coding at?

Here is an example :

class user
{
   char name[20] ;
   int number ;

   public :

   void getData()
   {
     cout << "\n Enter name and number : ";
     cin.getline( name, 20);
     cin >> number;
   }

   void putData()
   {
     cout << "\n Name : " << name ;
     cout << "\n Number : " << number ;
   }

   int returnNumber()
   {
      return number ;
   }

};

void searchUser( int num )
{
  int flag = 0;
  user newUser;

  fstream file("user.dat", ios::binary | ios::out | ios::in );

  while( !file.eof() )
  {
      file.read( (char*)&newUser, sizeof(newUser));
      if( newUser.returnNumber() == num )
      {
          newUser.putData();
          flag = 1;
          break;
      }
  }

  if( flag == 0 )
  {
      cout<<"\n User not present in database ";
  }

}

This is the code for searching and putting user data on screen. The function searchUser() is called upon from main() when user wants to search the database. The user enter the specific number that is to be searched. Call is like this :

int num ;

cin >> num;

searchUser(num);

Here I have implemented linear search. You can increase it's efficiency by implementing another efficient search algorithm ( probably binary search ).

Similarly you can input user info using the write() function that I said in previous post. With these functions, you can write or read a whole object in a single command, making your code more compact.

There is no need to read more than one record.

OK, sorry. didn't realize you only wanted to read the file once and input only the first username and password.

When I try to log in, it only accept admin1 as username and password1 as password.. If I try to log in using admin2, the program will return 'Invalid username or password.' instead of the welcome.

But you said you only wanted to read the first username and password! Make up your mind!!!

Are you under the impression readUserLog >> temp; reads every username at once?
Do you really think that if(userName == temp && password == temp1) tests every username from the file with the userName entered in one single statement?

Edited 4 Years Ago by WaltP

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