我目前正在做我的C++第一学期的最后一个项目(以及一般的编程)。我的教授希望我们做的是制作一个模拟的社交媒体程序,它具有一些基本功能,比如:
在提示符上他说:
期望看到有关材料的知识,特别是面向对象的设计类。
我认为这意味着我们应该正确地使用类。
这就引出了关于我所拥有的代码的一般性问题,即我是否满足了演示使用类(或对象或他可能期望的任何东西)的知识的“要求”。
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "project02.h"
using namespace std;
ofstream fout;
ifstream fin;
void LoginScreen()
{
cout << "Please select from the following options by entering the corresponding number:" << endl << endl;
cout << "1. Sign up" << endl;
cout << "2. Log in" << endl;
cout << "3. User list" << endl;
cout << "4. Exit" << endl << endl;
cout << "Please make your selection (enter 1, 2, 3, or 4): ";
}
void UserInfo::signUp()
{
int offset;
string line;
bool isTaken;
string fName;
string lName;
string bYear;
string screenName;
cout << "Enter your first name: ";
cin >> fName;
setFirstName(fName);
cout << "Enter your last name: ";
cin >> lName;
setLastName(lName);
cout << "Enter your birth year: ";
cin >> bYear;
setBirthYear(bYear);
cout << "Create your screen name (no special characters or spaces): ";
do
{
cin >> screenName;
isTaken = false;
fin.open("RegisteredUsers.txt");
while (!fin.eof())
{
getline(fin, line);
if ((offset = line.find(screenName, 0)) != string::npos)
{
isTaken = true;
cout << "The username " << screenName << " is already taken, please choose a different username: ";
}
}
fin.close();
} while (isTaken = true && isTaken != false);
setScreenName(screenName);
cout << endl;
cout << "Registered with the following information:" << endl;
cout << endl;
cout << "Full name: " << getFirstName() << " " << getLastName() << endl;
cout << "Birth year: " << getBirthYear() << endl;
cout << "Screen name: " << getScreenName() << endl;
cout << "You may now log in to your newly created account." << endl;
cout << endl;
string infoFileName = screenName + "_info.txt";
string followerFileName = screenName + "_follow.txt";
string activityFileName = screenName + "_activity.txt";
registerUser(fout, screenName);
fout.open(infoFileName.c_str());
writeUserInfo(fout, fName, lName, bYear, screenName);
fout.close();
}
void writeUserInfo(ofstream & fout, string & first, string & last, string & year, string & screen)
{
fout << first + " " + last + " " + year + " " + screen + " ";
}
void registerUser(ofstream & fout, string screen)
{
fout.open("RegisteredUsers.txt", ios::app);
fout << " " + screen;
fout.close();
}
void listUsers()
{
ifstream fin;
string screen;
cout << "The following users are registered: " << endl << endl;
fin.open("RegisteredUsers.txt");
while(!fin.eof())
{
fin >> screen;
cout << screen << endl;
}
fin.close();
}
void UserInfo::signIn()
{
int offset;
string line;
bool exists;
string screenName;
cout << "Please enter your screen name to sign in: ";
do
{
cin >> screenName;
exists = true;
fin.open("RegisteredUsers.txt");
while (!fin.eof())
{
getline(fin, line);
if ((offset = line.find(screenName, 0)) == string::npos)
{
exists = false;
cout << endl;
cout << "User " << screenName << " does not exist!" << endl << endl;
cout << "Please enter an existing username to sign in: ";
}
}
fin.close();
} while (exists = false || exists != true);
cout << "You are now logged in as " + screenName << endl;
}
void UserInfo::displayProfile()
{
}
void UserInfo::setFirstName(string fName)
{
_firstName = fName;
}
string UserInfo::getFirstName()
{
return _firstName;
}
void UserInfo::setLastName(string lName)
{
_lastName = lName;
}
string UserInfo::getLastName()
{
return _lastName;
}
void UserInfo::setBirthYear(string bYear)
{
_birthYear = bYear;
}
string UserInfo::getBirthYear()
{
return _birthYear;
}
void UserInfo::setScreenName(string screenName)
{
_screenName = screenName;
}
string UserInfo::getScreenName()
{
return _screenName;
}#ifndef PROJECT02_H
#define PROJECT02_H
using namespace std;
void LoginScreen();
void writeUserInfo(ofstream & fout, string & first, string & last, string & year, string & screen);
void registerUser(ofstream & fout, string screen);
void listUsers();
class UserInfo
{
public:
string getFirstName();
void setFirstName(string first);
string getLastName();
void setLastName(string last);
string getBirthYear();
void setBirthYear(string year);
string getScreenName();
void setScreenName(string sn);
void signUp();
void signIn();
void displayProfile();
private:
string _firstName;
string _lastName;
string _birthYear;
string _screenName;
};
#endif // PROJECT02_H#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "project02.h"
using namespace std;
int main()
{
char input;
UserInfo inputInfo;
cout << "Welcome to MyFace, a social media network where you can post your thoughts and see what your friends are up to." << endl << endl;
do
{
LoginScreen();
cin >> input;
cout << endl;
if (input == '1' && input != '2' && input != '3')
{
inputInfo.signUp();
}
else if (input == '2' && input != '3')
{
inputInfo.signIn();
}
else if(input == '3')
{
listUsers();
cout << endl;
system("PAUSE");
cout << endl;
LoginScreen();
}
else if (input != '1' && input != '2' && input != '3' && input != '4')
{
cout << "Invalid choice! Redirecting to login page..." << endl << endl;
}
else if (input == '4')
{
cout << "Thank you for using MyFace." << endl;
}
} while (input != '4');
return 0;
}正如您所看到的,它还没有包含所有的功能,而且signIn()实际上还没有做任何事情,因为这就是我停止的地方。无论如何,我仍然只是一个初学者,但请告诉我,如果你看到任何潜在的问题,如果我没有正确地使用课程,或如果你只是有任何一般性意见!
实际上,我没有太多的时间来完成这个任务,所以如果有些东西不需要修复,那么我可能不想修复它,特别是如果它涉及到沉重的重组或其他时间消耗。
发布于 2015-12-07 07:15:34
using namespace std;被认为是不好的做法。在C++中,短代码不是必需的,首选是清晰的代码。
return 0;是C语言遗留下来的,在C++中,不再需要在main的末尾手动编写它。如果没有遇到抛出或其他返回(如-1)的错误,编译器将负责返回“normal”。
如果您以后需要使用project02这样的名称,那么很难找到它的一部分。试着给它起一个更有意义的名字。
以下是令人困惑的问题:
else if (input != '1' && input != '2' && input != '3' && input != '4')为什么这不仅仅是最新的else语句?如果其他ifs没有一个是真的,则输入是无效的,并且应该是无效的。
发布于 2015-12-07 20:30:50
我可以在您的代码中发现一些事情(怀疑它已经按预期工作了),应该(实际上需要)加以改进:
的使用
流鳍;
这些不应该是全局变量,而是使用它们的函数中的局部变量,或者封装在管理所有用户注册的另一个类中。
中eof()的使用
时间(!fin.eof())
而使用
while(getline(fin, line))在循环条件下直接使用eof()测试几乎总是被认为错了。
只需测试输入操作是否良好,如上面所示。
main()循环的简化
主输入循环中的if/else if级联应该使用switch简化
bool exit = false;
do {
LoginScreen();
cin >> input;
switch(input) {
case '1':
inputInfo.signUp();
break;
case '2':
inputInfo.signIn();
break;
case '3':
listUsers();
cout << endl;
system("PAUSE");
break;
case '4':
exit = true;
break;
default:
cout << "Invalid choice! Redirecting to login page..." << endl;
break;
}
} while (!exit);中过度使用误用的多余endl
如前所述,但这可能是品味的问题。
就像这里
而(存在=假的存在!=真);
或者在这里
而(isTaken = true & isTaken != false);
这两种情况中的任何一种已经意味着另一种情况将成为true。
(Note there's also a possible error: to test for equality use `==`, I don't believe the assignment `=` is used intentionally in these cases, correct me if I'm wrong about this please).system("PAUSE");不是可移植的而是使用类似的东西
cout << "Press ENTER to continue" << endl;
getchar();using namespace std;在头文件中的使用
您不应该在头文件中使用此语句(或任何其他using namespace xyz;)。如果你确定你在做什么的话,在翻译部门是可以的。
But where header files are included is out of your control, and the `using namespace` statement may lead to unexpected namespace clashes.相反,要在头文件中显式地使用限定作用域限定符(例如std::string),并删除using namespace std;。
我非常肯定,仍然有更多的空间来改进您的代码(关于您的需求)。例如,如我在第一点中提到的那样,引入更多相互交互的类,比如RegistrationManager类,它实际上将负责管理已经注册的用户存储的文件,并在那里查找相应的记录。
附带说明:在非常第一的地方,确保它在代码审查时按照预期的方式工作。
https://codereview.stackexchange.com/questions/113119
复制相似问题