C++用户认证程序故障:含空格用户名登录失败
Fix for Username with Spaces in C++ User Authentication Program
Root Cause
Your login logic fails for usernames with spaces because:
- You're using spaces to separate usernames and passwords in the
record.txtfile. This creates ambiguity when usernames themselves contain spaces. - The
>>extraction operator stops reading at the first whitespace character. So when reading a username like "John Doe", it only captures "John", leaving "Doe" to be read as the password—this causes a mismatch with the actual password stored.
Solution
To fix this, we'll:
- Use a unique delimiter (tab character
\t) instead of spaces to separate username and password in the file. This ensures we can reliably split the stored data into username and password. - Read the entire line from the file during login, then split it using the tab delimiter to get the full username and password.
Modified Code
#include <iostream> #include <algorithm> #include <cctype> #include <fstream> #include <string> using namespace std; int main() { string User_Option; cout << "Do you want to Login Or Signup" << endl << endl; getline(cin, User_Option); transform(User_Option.begin(), User_Option.end(), User_Option.begin(), ::toupper); string Username_In_System; string Password_In_System; string Username; string Password; if (User_Option == "SIGNUP" || User_Option == "SIGN UP"){ ofstream RecordFile; RecordFile.open("record.txt"); cout << endl << endl << "USER AUTHENTICATION" << endl; cout << endl << "|*****************|" << endl; cout << endl << "SIGN UP FORM" << endl; cout << endl << "Enter Username: " << endl; getline(cin, Username_In_System); cout << endl << "Enter Password: " << endl; cin >> Password_In_System; cout << endl << endl << "Registration Success" << endl; // Use tab as delimiter instead of spaces RecordFile << Username_In_System << "\t" << Password_In_System << endl; RecordFile.close(); } else if (User_Option == "LOGIN" || User_Option == "LOG IN" || User_Option == "SIGNIN" || User_Option == "SIGN IN"){ ifstream InputFile; InputFile.open("record.txt"); cout << endl << endl << "USER AUTHENTICATION" << endl; cout << endl << "|*****************|" << endl; cout << endl << "SIGN IN FORM" << endl; cout << endl << "Enter Username: " << endl; getline(cin, Username); cout << endl << "Enter Password: " << endl; cin >> Password; string line; bool loginSuccess = false; // Read entire line from file if (getline(InputFile, line)) { // Split line at tab delimiter size_t tabPos = line.find('\t'); if (tabPos != string::npos) { Username_In_System = line.substr(0, tabPos); Password_In_System = line.substr(tabPos + 1); // Check credentials if (Username_In_System == Username && Password_In_System == Password) { loginSuccess = true; } } } if (loginSuccess) { cout << endl << "Login Success" << endl; } else { cout << endl << "Login Error" << endl; } InputFile.close(); } else { cout << endl << "Input Error" << endl; } return 0; }
Additional Notes
- If you want to allow passwords with spaces in the future, you'll need to use
getlinefor password input as well. However, this requires clearing the newline character left in the input buffer after previouscinoperations (you can usecin.ignore()for this). - Using a tab delimiter ensures that spaces in usernames don't interfere with splitting the stored credentials correctly.
内容的提问来源于stack exchange,提问作者Kingsford Quainoo
相关产品推荐
相关产品推荐

