我编写了我正在处理的代码的简化版本来说明我遇到的问题。我认为 main()
中有问题导致 showUsers()
方法为每个元素(总是最后添加的元素)输出相同的登录名/密码组合。
这是我的代码:
#include <iostream>
using namespace std;
//=============================================================================
class AccountInfo {
private:
char* _username;
char* _password;
public:
AccountInfo();
AccountInfo(char* username, char* password);
~AccountInfo();
void setUsername(char* username);
void setPassword(char* password);
char* getUsername();
char* getPassword();
friend ostream& operator<<(ostream& out, AccountInfo& x) {
out << "Login: " << x.getUsername() << endl
<< "Password: " << x.getPassword() << endl;
return out;
}
};
AccountInfo::AccountInfo() {
_username = "";
_password = "";
}
AccountInfo::AccountInfo(char* username, char* password) {
_username = username;
_password = password;
}
void AccountInfo::setUsername(char* username) {
_username = username;
}
void AccountInfo::setPassword(char* password) {
_password = password;
}
char* AccountInfo::getUsername() {
return _username;
}
char* AccountInfo::getPassword() {
return _password;
}
//=============================================================================
class UsersDB {
private:
int _size;
AccountInfo* _accounts[200];
public:
UsersDB();
~UsersDB();
int getSize();
void addUser(AccountInfo* newUser);
void showUsers();
};
UsersDB::UsersDB() {
_size = 0;
}
UsersDB::~UsersDB() {
delete[] _accounts;
}
int UsersDB::getSize() {
return _size;
}
void UsersDB::addUser(AccountInfo* newUser) {
_accounts[_size] = newUser;
_size++;
}
void UsersDB::showUsers() {
for (int i = 0; i < _size; i++) {
cout << *_accounts[i] << endl;
}
}
//---------------------------------------------------------emptyString function
void emptyString(char* token, int size) {
for (int i=0; i < size; i++) token[i] = '\0';
}
//----------------------------------------------------------copyString function
void copyString (char* from, char* to, int size) {
to = new char[size+1];
for (int i=0; i < size; i++) to[i] = from[i];
to[size] = '\0';
}
//--------------------------------------------------------getNextToken function
int getNextToken(char* buffer, char* token, int startPos,
int bufSize, int tokenSize, char delimeter) {
int i, j;
emptyString (token, tokenSize);
i = startPos;
j = 0;
while ((buffer[i] == ' ') && (i < bufSize)) i++; //skipblanks
if (i < 256) {
while ((buffer[i] != delimeter) && (i < 256) && (j < tokenSize))
token[j++] = buffer[i++];
}
return i;
}
//=============================================================================
int main() {
char buffer[256];
char userLoginName[9];
char password[17];
int i, j, k;
char flag[3];;
char command[11];
char blank = ' ';
UsersDB* users = new UsersDB();
AccountInfo* tempAccount;
while (!cin.eof()) { //while end of line is not reached
cin.getline(buffer, 256);
k = getNextToken(buffer, command, 0, 256, 10, blank);
if (command[0] == 'a') {
tempAccount = new AccountInfo();
k = getNextToken(buffer, userLoginName, k, 256, 8, blank);
(*tempAccount).setUsername(userLoginName);
k = getNextToken(buffer, flag, k, 256, 2, blank);
if (flag[1] == 'p') {
k = getNextToken(buffer, password, k, 256, 16, blank);
(*tempAccount).setPassword(password);
}
cout << *tempAccount << endl;
(*users).addUser(tempAccount);
}
else if (command[0] == 's') {
(*users).showUsers();
}
else cout << "Command not found." << endl;
}
return 0;
}
输出如下所示:
=============================================================================== >adduser bob -p password1 Login: bob Password: password1 >adduser jack -p mypassword Login: jack Password: mypassword >adduser jill -p pass1234 Login: jill Password: pass1234 >showusers Login: jill Password: pass1234 Login: jill Password: pass1234 Login: jill Password: pass1234 ===============================================================================
输出应该如下所示:
=============================================================================== >adduser bob -p password1 Login: bob Password: password1 >adduser jack -p mypassword Login: jack Password: mypassword >adduser jill -p pass1234 Login: jill Password: pass1234 >showusers Login: bob Password: password1 Login: jack Password: mypassword Login: jill Password: pass1234 ===============================================================================
注意:当我将 main()
(通过直接传递信息而不是使用 cin
从控制台获取信息)更改为如下所示时:
//============================================================================= int main() { UsersDB* users = new UsersDB(); AccountInfo* tempAccount; tempAccount = new AccountInfo("jack", "mypassword"); (*users).addUser(tempAccount); tempAccount = new AccountInfo("jill", "pass1234"); (*users).addUser(tempAccount); (*users).showUsers(); return 0; }
...我得到了想要的输出。
非常感谢。
最佳答案
你在你的类中使用了 char* 指针,它们不像“普通”字符串那样工作。当您将 char* 指针传递给方法并将其分配给成员变量时,您并没有复制字符串,只是使成员变量指向与参数指向的字符串相同的字符串。由于传入的所有参数都是指向输入缓冲区的指针,因此缓冲区中的下一个输入将覆盖所有先前对象中的文本。
在 C++ 中,你真的应该使用 std::string它不会传递 char* 来进行字符串操作,它会在这种情况下为您提供很大帮助,并且会自动为新字符串处理复制和分配内存。
后一个带有常量的版本起作用的原因是,您的对象最终指向的文本常量不会像您的缓冲区那样被覆盖。
关于C++ 指针数组为每个元素返回相同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9107809/