You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++银行应用登录功能报错:std::basic_istream与string无法比较

银行应用登录功能报错修复方案

问题背景

我正在开发一款银行应用,已实现账户创建功能,可对密码、SSN等数据加密。登录环节需要读取BankUsersFiles.txt中的加密密码,与用户输入后加密的密码比对,匹配则调用主应用函数并输出"You Are in!",但运行时出现编译错误。

报错信息

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

相关代码

登录函数代码

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();
       }
   }
}

账户创建函数代码

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();
        }
    }
  
}

加密相关代码

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;
}

问题分析与修复方案

核心错误原因

  1. for循环条件错误:getline(b2, UserData.Username) == LoginUsername 中,getline返回的是istream对象,不能直接和string比较,这是编译报错的直接原因。
  2. 密码比对逻辑错误:LoginCodedPassword == getline(b2,UserData.codedPassword) 同样犯了上述错误,且UserData.codedPassword是vector<int>类型,无法直接用getline读取文本中的数据(因为写入时是直接输出vector,实际存储的是空格分隔的数字)。
  3. 输入流残留问题:创建账户时用cin >> choice后,输入流中会残留换行符,导致后续getline读取空字符串。

修复后的登录函数

#include <sstream>
#include <limits>

void LoginToAccount()
{
    vector<int> LoginCodedPassword;
    string LoginPassword;
    string LoginUsername;
    string line;
    bool foundUser = false;

    ifstream b2("BankUsersFiles.txt"); 
    if (!b2.is_open()) {
        cerr << "Failed to open user file!" << endl;
        return;
    }

    cout << "LOGIN" << endl;
    cout << "Please Enter Your Username" << endl;
    // 处理输入流残留的换行符
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    getline(cin, LoginUsername);

    // 遍历文件查找目标用户
    while (getline(b2, line)) {
        if (line == LoginUsername) {
            foundUser = true;
            // 读取存储的加密密码行并解析为vector<int>
            vector<int> storedCodedPassword;
            string passwordLine;
            getline(b2, passwordLine);
            stringstream ss(passwordLine);
            int num;
            while (ss >> num) {
                storedCodedPassword.push_back(num);
            }

            // 获取用户输入的密码并加密
            cout << "Please Enter Your Password" << endl;
            getline(cin, LoginPassword);
            LoginCodedPassword = encoder(LoginPassword);

            // 比对加密密码
            if (LoginCodedPassword == storedCodedPassword) {
                MainApplication();
                b2.close();
                return;
            } else {
                cout << "Incorrect password!" << endl;
                b2.close();
                return;
            }
        } else {
            // 跳过当前用户的其他信息(密码、地址、SSN)
            for (int i = 0; i < 3; ++i) {
                getline(b2, line);
            }
        }
    }

    if (!foundUser) {
        cout << "User not found!" << endl;
    }
    b2.close();
}

额外修复点

  1. 账户创建函数的输入流处理:在cin >> choice后添加换行符忽略,避免后续getline读取异常:
cin >> choice;
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 添加该行
switch(choice) {
    // ... 原有代码
}
  1. 初始化加密密钥:在程序启动时调用primefiller()和setkeys(),否则加密功能会失效,比如在main函数中:
int main() {
    primefiller();
    setkeys();
    CreateUserAccount();
    return 0;
}

说明

  • 修复了getline与字符串直接比较的语法错误,改用先读取到字符串再比对的逻辑。
  • 实现了文本中加密密码的解析逻辑,将存储的数字字符串转换为vector<int>后再和用户输入加密后的密码比对。
  • 处理了输入流的残留换行符问题,避免读取空数据。
  • 添加了文件打开失败的判断,增强程序健壮性。

内容的提问来源于stack exchange,提问作者WillBeTheBestInTheFuture

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:13:14