I am trying to use classes in C++ - c++

I am working on a project where I think a need to use classes. I want to make a bank system and for that I need to create accounts formed by a password and a name. The problem is when I try to make a new account, the previous account is deleted so I can have just one account at a time.
I researched on internet and I think the solution is to use classes. Can somebody help me with an adivice or a ideea? I will attach the code below.
The function
Main
In the file Input.txt I add initial 1 and then increase in variable cont with every account created. The problem is the file Conturi.txt because there I have only one account, the latest one and I don t know why because a make a write everytime i use the void creare_cont....

First of all please format your code. And attach it into your question.
To write a banking system you can obviously use classes. But that's not the case here.
Your problem is not with classes but with application's logic. It's hard to tell exactly what your code suppose to do, because it is incomplete and I'm not familiar with Romanian, but I'll try to guess.
When you try to write such a project, you must first ask yourself a few questions:
What does the banking system do?
What features should it have?
What kind of data does it store?
How will this data be stored?
I think we all know answer to first question: It keeps customers money. That was easy.
Based on the published code, I'll try to answer the remaining questions.
What features should it have?
I translated your menu into something like this:
Create a new bank account.
Log into an existing account.
Display balance of existing accounts.
What kind of data does it store?
Let's keep it very simple and store only username, password and user's balance. To do so we will create our own structure. We could use classes, but as I said: keep it simple and short.
struct BankAccount
{
std::string username;
std::string password;
int balance;
};
How will this data be stored?
To store some data we usually usesome kind of database. I'll use a simple file just as you did. But first we must decide how to store accounts inside our database? I would suggest again to keep it simple and make few rules:
Username and password can't contain any whitespaces
Password will be stored in plain text
Balance must fit into int
Everything will be separated by a space
I would add one more rule (to make it more readable in case of debugging): Every user will be kept in different line. So our database might look like this:
adam pass 123
eva qwerty 666
henry qaz123 -100
... and so on ...
After answering all our questions, we can start thinking on how our system should work?
How should it work?
I would split our logic into 4 steps:
Load the database.
Ask user what to do.
Do whatever user requested.
Save the database.
Of course this is not the best or fastest way of doing this. But as I said: Keep it simple. We will also assume that database is not corrupted, so we won't have to validate it on loading.
Now let's divide each step into atoms.
1. Load the database.
To do that we need a file with data and some kind of structure to load data into. We will use std::vector because it can extend automatically and we won't have to worry about it. Now, what do we need to do? We know exactly how our file is structured and we can assume that database is not corrupted. So all we need to do is read characters until we will encounter a whitespace. Fortunately we can do it without writing any sophisticated functions. Standard library will do it for us:
#include <vector>
#include <string>
#include <fstream>
std::vector<BankAccount> LoadDatabase(const std::string &dbFile)
{
std::vector<BankAccount> accounts;
std::ifstream file(dbFile);
if (!file)
{
std::cerr << "Cannot open database file!" << std::endl;
return accounts;
}
BankAccount account;
while (file >> account.username >> account.password >> account.balance)
accounts.push_back(account);
return accounts;
}
Because every field in our database is separated by space we can easly read the whole file. I'll leave implementation of SaveDatabase(const std::string &dbFile, const std::vector<BankAccount> &accounts) to you. It should be very similar to our loading function.
2. Ask user what to do.
I won't write this code either. You already did this. What I can do is suggest you to move it into separate function and return the result (requested action). You should keep asking for user's input until it is valid (i.e. it is an integer and corresponds to any element in the menu).
3. Do whatever user requested.
Now we should call apropriate function based on what user choosed in previous step. We will use switch statement for it. I translated (so blame Ggoogle if anything is wrong) your menu to know what kind of features we must implement and I ended with these three:
Create a new bank account.
Log into an existing account.
Display balance of existing accounts.
Creating a new account should be very easy. We already have our database loaded in std::vector and we know that it will be saved back to the file when closing the application. All we have to do is ask for new user data (username and password), build a new object and add it to std::vector. It may look like this:
void CreateAccount(std::vector<BankAccount> &accounts)
{
BankAccount account;
std::cout << "Provide username and password (separated by space):" << std::endl;
std::cin >> account.username >> account.password.
account.balance = 0;
accounts.push_back(account);
}
I have no idea what logging in to an existing account should do (maybe display a new menu?), so I'll leave it to you to write. But displaying balance of all accounts should be easy:
void DisplayAllAccounts(const std::vector<BankAccount> &accounts)
{
std::cout << "All accounts in database:\n";
for (size_t i = 0; i < accounts.size(); ++i)
std::cout << "\t" << accounts[i].username << " has $" << accounts[i].balance << "\n";
}
4. Save the database.
As I said, I'll leave it to you. Shouldn't be that hard to write based on what you have now.
Oh, I would forget. Your main function with switch statement:
int main()
{
const std::string dbFile = "Conturi.txt";
// Load the database
std::vector<BankAccount> accounts = LoadDatabase(dbFile);
// SelectAction shows the menu, gathers user's input and return 1, 2 or 3 depending on action he choosed
switch(SelectAction())
{
case 1:
CreateNewAccount(accounts);
break;
case 2:
LogIntoAccount(accounts);
break;
case 3:
DisplayAllBalances(accounts);
break;
default:
// This should never happend because SelectAction should handle incorrect input
std::cerr << "Incorrect input!" << std::endl;
return 1;
}
// Save the database
SaveDatabase(dbFile, accounts);
return 0;
}
As you can see it wasn't that hard. And code is more readable when it's properly formated.
Now that I've done most of your homework, good luck with the rest!

Related

Intercepting all orders with full data in MT4

I'm trying to write a trade copier for MT4. I have already written one for MT5, but the issue I'm having with translation is in intercepting active orders. In MT5, this is relatively simple:
void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request,
const MqlTradeResult &result) {
// Code goes here
}
As shown in the MQL5 documentation, this event intercepts all orders sent from the client and accepted by a trade server.
Looking at the MQL4 documentation, however, I don't see any easy way of doing this. The closest I could get would be to iterate over all the orders by doing this:
for (int i = 0; i < OrdersTotal(); i++) {
if (!OrderSelect(i, SELECT_BY_POS)) {
// Error handling here
}
// Do stuff with this order
}
My understanding is that this code also gets all open orders. However, the issue I'm having is that there are key pieces of information that I cannot determine on these orders:
Slippage
Position-by (for close-by orders)
Action type (close, close-by, delete, modify, send). Although this could be inferred from the fields populated on the order.
In my mind, I could then go and intercept the orders when they're generated (i.e. wrap OrderClose, OrderCloseBy, OrderDelete, OrderModify and OrderSend) and pull the relevant information off of the orders that way. But that still doesn't cover the case where the user enters an order manually.
Is there a way I can intercept all orders data without losing information?

A simple command in PAWN

San Andreas Multiplayer (GTA) uses PAWN as its programming language. I'm an owner of a server on SA-MP and I'm not that pro so I'd like to get some help if possible. Basically, I have a command that checks player's statistics when he/she is online, but I'd like to have a command to check them when they're offline. That's the code of the commmand which checks player's statistics when he's online.
CMD:check(playerid, var[])
{
new user;
if(!Logged(playerid)) return NoLogin(playerid);
if(Player[playerid][pAdmin] >= 2 || Player[playerid][pStaffObserver])
{
if(sscanf(var,"us[32]", user, var))
{
SendClientMessage(playerid, COLOR_WHITE, "{00BFFF}Usage:{FFFFFF} /check [playerid] [checks]");
SendClientMessage(playerid, COLOR_GRAD2, "** [CHECKS]: stats");
return 1;
}
if(!strcmp(var, "stats", true))
{
if(!Logged(user)) return NoLoginB(playerid);
ShowStats(playerid, user);
}
}
else
{
NoAuth(playerid);
}
return 1;
}
I use ZCMD command processor and Dini saving system. So I'd like to make CMD:ocheck that would display the stock ShowStats and it'll work like /ocheck [Firstname_Lastname].
Any help? Please help if possible.
Thanks
~Kevin
For the command that you require, you'll have to load data from the player's userfile.
You'll obviously begin with
if(!Logged(playerid)) return NoLogin(playerid);
if(Player[playerid][pAdmin] >= 2 || Player[playerid][pStaffObserver])
{
To check if the player using this is authorized to use this command.
Following this,
if(str, "s[32]", name))
You cannot use 'u' as a formatter here, simply because you're checking an offline player's statistics.
After this, you need to check if the user is actually registered
If he isn't, you return that error the user of this command
If he is, then check if he is online already. If he is online, return error to admin to use this command instead of 'ocheck'
If he's offline, then you can safely proceed to load his statistics (you can use the code used for loading data when a player logs in, except this time it should only be printed
for eg,
format(str, sizeof(str),
"Score: %s, Money: %d",
dini_Int(file, "score"), dini_Int(file, "score") );
Yes, basically, you have to get all the information from the file, so ShowStats will not work, because I suppose it gets all the information from enumerations and such, you have to write a brand new function, of getting all the offline info.

Steam API getting persona name

I have been following the Steam documentation to a t, but I have gotten to the point where I need to retrieve player names based on the steam ID, and Steam has a function for this in their documentation:
const char *pchName = SteamFriends()->GetPersonaName(steamID);
However Visual Studio says that there is no function with that number of arguments. The only acceptable function is
const char *pchName = SteamFriends()->GetPersonaName();
Which is supposed to return the local player's persona name (which it does). I can make a way to get this from every user and store it on my server on login, but it sure seems like this should work. How am I supposed to get the persona name for a friend's uint64 SteamID? Did they change this function recently?
I am using Unreal Engine 4.7.6 from source with Steam API 1.30.
Apparently Steam is bad at updating their documentation. I opened up the isteamfriends.h header and found this function that is never mentioned in the Steam docs:
// returns the name another user - guaranteed to not be NULL.
// same rules as GetFriendPersonaState() apply as to whether or not the user knowns the name of the other user
// note that on first joining a lobby, chat room or game server the local user will not known the name of the other users automatically; that information will arrive asyncronously
//
virtual const char *GetFriendPersonaName( CSteamID steamIDFriend ) = 0;
Come on, Steam... I literally pulled this line directly from their live docs about 30 minutes ago, and it doesn't work.
const char *pchName = SteamFriends()->GetPersonaName(steamID);
So the correct way then is:
const char *pchName = SteamFriends()->GetFriendsPersonaName(steamID);

c++ driver mongodb connection options

It seems that c++ drivers doesn't accept mongodb connection uri format.
There's no documentation on how i should create connection string, any guess?
I need to connect to a replica set with 3 servers, and set readPreference options.
Create a connection to a replica set in MongoDB C++ client
Until the problems explained in #acm's answer are resolved, I have found a workaround to the bad Connection Strings of the C++ driver. You can create a DBClientReplicaSet using a vector of hosts and ports this way:
//First create a vector of hosts
//( you can ignore port numbers if yours are default)
vector<HostAndPort> hosts;
hosts.push_back(mongo::HostAndPort("YourHost1.com:portNumber1"));
hosts.push_back(mongo::HostAndPort("YourHost2.com:portNumber2"));
hosts.push_back(mongo::HostAndPort("YourHost3.com:portNumber3"));
//Then create a Replica Set DB Client:
mongo::DBClientReplicaSet connection("YourReplicaSetName",hosts,0);
//Connect to it now:
connection.connect();
//Authenticate to the database(s) if needed
std::string errmsg;
connection.auth("DB1Name","UserForDB1","pass1",errmsg);
connection.auth("DB2Name","UserForDB2","pass2",errmsg);
Now, you can use insert, update, etc. just as you did with DBClientConnection. For a quick fix, you can replace your references to DBClientConnection with DBClientBase (which is a parent to both DBClientConnection and DBClientReplicaSet)
Last pitfall: if you are using getLastError(), you must use it with the aimed database name like this:
connection.getLastError(std::string("DBName"));
cause otherwise it will always return "command failed: must log in" as described in this JIRA ticket.
Set the read preferences for every request
You have two ways to do that:
SlaveOK option
It lets your read queries be directed to secondary servers.
It takes place in the query options, which are at the end of the parameters of DBClientReplicaSet.query(). The options are listed in Mongo's official documentation
The one you would look for is mongo::QueryOption_SlaveOk, which will allow you to have reads made on secondary instances.
This is how you should call query();
connection.query("Database.Collection",
QUERY("_id" << id),
n,
m,
BSON("SomeField" << 1),
QueryOption_SlaveOk);
where n is the number of documents to return (0 if you don't want any limit), m the number to skip (defaults to 0), the next field is your projection and the last your query option.
To use several query option, you can use bitwise or | like this :
connection.query("Database.Collection",
QUERY("_id" << id),
n,
m,
BSON("SomeField" << 1),
QueryOption_SlaveOk | QueryOption_NoCursorTimeout | QueryOption_Exhaust);
Query::readPref option
The Query object has a readPref method which sets read preferences for a special query. It should be called for each query.
You can pass different arguments for more control. They are listed here.
So here's what you should do (I did not test that one cause I can't right now but it should work just fine)
/* you should pass an array for the tags. Not sure if this is required.
Anyway, let's create an empty array using the builder. */
BSONArrayBuilder bab;
/* if any, add your tags here */
connection.query("Database.Collection",
QUERY("_id" << id).readPref(ReadPreference_SecondaryPreferred, bab.arr()),
n,
m,
BSON("SomeField" << 1),
QueryOption_NoCursorTimeout | QueryOption_Exhaust);
Note: if any readPref option is used, it should override the slaveOk option.
Hope this helped.
Please see the connection string documentation for details on the connection string format.
(code links below are to 2.2.3 files)
To use a connection string with the C++ driver, you should use the ConnectionString class. You first call the ConnectionString::parse static method with a connection string to obtain a ConnectionString object. You then call ConnectionString::connect to obtain a DBClientBase object which you can then use to send queries.
As for read preference, at the moment I do not see a way to set the read preference in the connection string for the C++ driver, which would preclude a per-connection setting.
However, the implementation of DBClientBase returned by calling ConnectionString::parse with a string that identifies a replica set will return you an instance of DBClientReplicaSet. That class honors $readPreference in queries, so you can set your read preference on a per-query basis.
Since the current C++ drivers still do not accept the standard mongodb connection URIs, I've opened a ticket:
https://jira.mongodb.org/browse/CXX-2
Please vote for it to help get this fixed.
it seems like you can set read Preference before send a read request by call "readPref" method of your Query object. I'v not found a way to set read Preference on mongo collection object yet.

Doctrine2, update some datas before persist

I'm developing my php software using Doctrine2. It is quite simple to use it but I have a little problem and I would know what is the best practice in that situation. Maybe you could help me ! You'll have all my gratitude :-D
Situation :
I have 2 entities (User and Contacts)
A User can contain some Contacts
The entity (table) Contacts have a field labelled mainContact which define if it is the main contact of the user or not.
Ony one contact could be the main contact (mainContact=1)
Problematic :
I woud like that when I persist a contact :
If this contact has mainContact=1, all other contacts associated to
the user sould be updated to mainContact=0
If this contact has mainContact=0, I need to check all other
contacts. If I don't find any other contact with mainContact=1 for
this user, I automaticly update the current contact with
setMainContact(true).
Possible solutions :
I have some idea how to process this logic but I would like to know the best practice in order to do a good code because this application will be an open source application.
Not clean ideas :
Create a method in the Contact Repository that will update all the
others contacts assigned to the user and return the value to
attribute to the current contact.
With this solution, I must launch the repository method always before to persist a contact all around the application. If I forgot to launch it, the database integrity should be compromised.
Use the Prepersist mecanism from the entity to get the entitymanager
and update all others user's contacts.
This method is not recommanded, the entity should never access directly the entity manager.
Can anyone tell me what is the best practice to do so ? Thank you very much !
PS : Sorry for my poor english !
The best thing you can do here (from a pure OOP perspective, without even the persistence logic) is to implement this logic in your entity's setters. After all, the logic isn't heavy considered that a User won't have many contacts, nor the operation will happen very often.
<?php
class User
{
protected $contacts;
// constructor, other fields, other methods
public function addContact(Contact $contact)
{
if ($this->contacts->contains($contact)) {
return;
}
if ($contact->isMainContact()) {
foreach ($this->contacts as $existingContact) {
$existingContact->setMainContact(false);
}
$this->contacts->add($contact);
$contact->setUser($this); // set the owning side of the relation too!
return;
}
$mainContact = true;
foreach ($this->contacts as $existingContact) {
if ($existingContact->isMainContact()) {
$mainContact = false;
break; // no need for further checks
}
}
$contact->setMainContact($mainContact);
$this->contacts->add($contact);
$contact->setUser($this); // set the owning side of the relation too!
}
}
On the other side, think about adding a field to your user instead:
<?php
class User
{
// keep reference here instead of the contact (cleaner)
protected $mainContact;
}