c++stringoperatorsgetline

How to getline from txt file and check if it is correct with what the user inputed


I am creating a bank application.

So far, I can create an account. After that, it encrypts the data like password and SSN. After that, it takes me to the login function where I have to enter my user name and password.

I want to read the lines in my bankUsersFile to take the encrypted password and set it equal to the password I entered. The password that I enter is also quickly encrypted then they are set equal in an if statement. If they are correct, it calls the main bank application function and it prints "you are in".

I tried doing this:

void LoginToAccount()
{
   vector<int> LoginCodedPassword;
   string LoginPassword;
   string LoginUsername;
    
   ifstream b2("BankUsersFiles.txt"); 
   
   cout << "LOGIN" << endl;
   cout << "Please Enter Your Username" << endl;
   getline(cin, LoginUsername);
   for (getline(b2, UserData.Username) == LoginUsername)
   {
       cout << "Please Enter Your Password" << endl;
       getline(cin, LoginPassword);
       LoginCodedPassword = encoder(LoginPassword)
       if(LoginCodedPassword == getline(b2,UserData.codedPassword))
       {
           MainApplication();
       }
   }

My create account function:

void CreateUserAccount()
{
    ofstream b1("BankUsersFiles.txt", ios::app);
    int choice = 0;
    string VerifyPassTemp;
    
    cout << "1. Create New Account" << endl;
    cout << "2. Switch to Login" << endl;
    cout << "3. Exit Program" << endl;
    
    cin >> choice;
    switch(choice)
    {
        case 1:
        {
            cout << "Please Enter Your Username: " << endl;
            cin >> UserData.Username;
            cout << "Please Enter Your Password: " << endl;
            cin >> UserData.Password;
            cout << "Please verify your Password: " << endl;
            cin >> VerifyPassTemp;
            UserData.codedPassword = encoder(UserData.Password);
            if (VerifyPassTemp == UserData.Password)
            {
                UserData.LoginPassword = "0";
                cout << "Please Enter Your Current Adress: " << endl;
                cin >> UserData.Adress;
                cout << "Please Enter Your SSN" << endl;
                cin >> UserData.SSN;
                UserData.codedSSN = encoder(UserData.SSN);
                UserData.SSN = "0";
                
                b1 << UserData.Username << endl << UserData.codedPassword << endl << UserData.Adress << endl << UserData.codedSSN << endl;
            }
            else
            {
                break;
            }
            
            b1.close();
            
            LoginToAccount();
        }
        case 2:
        {
            LoginToAccount();
        }
    }
  
}

But I get this error:

‘operator==’ (operand types are ‘std::basic_istream’ and ‘std::string’ {aka ‘std::__cxx11::basic_string’})

My encoder also works fine.

I do not know how I can possibly fix this issue!

Also, I am using a vector<int> because of my encoder:

set<int>
    prime; // a set will be the collection of prime numbers,
           // where we can select random primes p and q
int public_key;
int private_key;
int n;
// we will run the function only once to fill the set of
// prime numbers

void MainApplication()
{
    cout << "You Are in!" << endl;
}

void primefiller()
{
    // method used to fill the primes set is seive of
    // eratosthenes(a method to collect prime numbers)
    vector<bool> seive(250, true);
    seive[0] = false;
    seive[1] = false;
    for (int i = 2; i < 250; i++) {
        for (int j = i * 2; j < 250; j += i) {
            seive[j] = false;
        }
    } // filling the prime numbers
    for (int i = 0; i < seive.size(); i++) {
        if (seive[i])
            prime.insert(i);
    }
}
// picking a random prime number and erasing that prime
// number from list because p!=q
int pickrandomprime()
{
    int k = rand() % prime.size();
    auto it = prime.begin();
    while (k--)
        it++;
    int ret = *it;
    prime.erase(it);
    return ret;
}
void setkeys()
{
    int prime1 = pickrandomprime(); // first prime number
    int prime2 = pickrandomprime(); // second prime number
    // to check the prime numbers selected
    // cout<<prime1<<" "<<prime2<<endl;
    n = prime1 * prime2;
    int fi = (prime1 - 1) * (prime2 - 1);
    int e = 2;
    while (1) {
        if (__gcd(e, fi) == 1)
            break;
        e++;
    } // d = (k*Φ(n) + 1) / e for some integer k
    public_key = e;
    int d = 2;
    while (1) {
        if ((d * e) % fi == 1)
            break;
        d++;
    }
    private_key = d;
}
// to encrypt the given number
long long int encrypt(double message)
{
    int e = public_key;
    long long int encrpyted_text = 1;
    while (e--) {
        encrpyted_text *= message;
        encrpyted_text %= n;
    }
    return encrpyted_text;
}
// to decrypt the given number
long long int decrypt(int encrpyted_text)
{
    int d = private_key;
    long long int decrypted = 1;
    while (d--) {
        decrypted *= encrpyted_text;
        decrypted %= n;
    }
    return decrypted;
}
// first converting each character to its ASCII value and
// then encoding it then decoding the number to get the
// ASCII and converting it to character
vector<int> encoder(string message)
{
    vector<int> form;
    // calling the encrypting function in encoding function
    for (auto& letter : message)
        form.push_back(encrypt((int)letter));
    return form;
}

enter image description here


Solution

  • You are using std::getline() the wrong way on these lines:

    for (getline(b2, UserData.Username) == LoginUsername)
    ... 
    if(LoginCodedPassword == getline(b2,UserData.codedPassword))
    

    std::getline() returns a reference to the std::istream that you pass in the 1st parameter. You can't compare a std::istream object to a std::string object, hence the error. std::getline() modifies the std::string that you pass in the 2nd parameter, you need to compare that value instead.

    However, note that codedPassword (and codedSSN) is a std::vector, and you can't use std::getline() to read in a std::vector like you are attempting to do. You are writing codedPassword (and codedSSN) to the file using operator<<, but there is no operator<< in the standard library for writing a std::vector to a std::ostream, so you must write your own. In which case, you should also write a corresponding operator>> to read in a std::vector to match.

    Also, your CreateUserAccount() function is writing 4 lines per user to the text file. So your LoginToAccount() function needs to read in 4 lines at a time to match.

    Try something more like this:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <limits>
    ...
    using namespace std;
    
    ostream& operator<<(ostream &out, const vector<int> &vec) {
        // there is no standard way to write out a vector to
        // a stream, so write out the contents as desired...
        return out;
    }
    
    istream& operator>>(istream &in, vector<int> &vec) {
        // there is no standard way to read in a vector from
        // a stream, so read in the contents as desired...
        return in;
    }
    
    istream& skipLine(istream &in) {
        return in.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    
    void LoginToAccount()
    {
        string LoginPassword;
        string LoginUsername;
           
        cout << "LOGIN" << endl;
    
        cout << "Please Enter Your Username" << endl;
        getline(cin, LoginUsername);
    
        cout << "Please Enter Your Password" << endl;
        getline(cin, LoginPassword);
    
        vector<int> LoginCodedPassword = encoder(LoginPassword);
    
        ifstream b2("BankUsersFiles.txt"); 
    
        while (getline(b2, UserData.Username) &&
               (b2 >> UserData.codedPassword))
        {
            if ((LoginUsername == UserData.Username) &&
                (LoginCodedPassword == UserData.codedPassword))
            {
                MainApplication();
                return;
            }
    
            skipLine(b2); // the rest of the password line
            skipLine(b2); // the address line
            skipLine(b2); // the ssn line
        }
    
        cout << "Incorrect Login" << endl;
    }
    
    void CreateUserAccount()
    {
        string VerifyPassTemp;
        
        cout << "Please Enter Your Username: " << endl;
        cin >> UserData.Username;
    
        cout << "Please Enter Your Password: " << endl;
        cin >> UserData.Password;
    
        cout << "Please verify your Password: " << endl;
        cin >> VerifyPassTemp;
    
        if (VerifyPassTemp != UserData.Password)
        {
            cout << "Passwords do not match" << endl;
            return;
        }
    
        UserData.codedPassword = encoder(UserData.Password);
        UserData.Password = "";
    
        cout << "Please Enter Your Current Adress: " << endl;
        cin >> UserData.Adress;
    
        cout << "Please Enter Your SSN" << endl;
        cin >> UserData.SSN;
    
        UserData.codedSSN = encoder(UserData.SSN);
        UserData.SSN = "";
                    
        ofstream b1("BankUsersFiles.txt", ios::app);
        b1 << UserData.Username << '\n'
           << UserData.codedPassword << '\n'
           << UserData.Adress << '\n'
           << UserData.codedSSN << '\n';
    }
    
    void Menu()
    {
        cout << "1. Create New Account" << endl;
        cout << "2. Switch to Login" << endl;
        cout << "3. Exit Program" << endl;
        
        int choice = 0;
        cin >> choice;
    
        switch (choice)
        {
            case 1:
            {
                CreateUserAccount();
                LoginToAccount();
                break;
            }
    
            case 2:
            {
                LoginToAccount();
                break;
            }
        }  
    }