How to have all options in one function? - c++

So i'm making a text adventure game and I want to be able to have a function which has all the inputs in it. So instead of every time me making an if statement to check for every direction I can just put a function that has all of that in it. How do I make this?
string input;
while (input != "n", "s", "e", "w")
{
getline(cin, input);
if (input == "n")
{
dTable();
}
if (input == "e")
{
cout << "You sit on the sofa. Congratulations" << endl;
}
if (input == "w")
{
cout << "You just ran into a wall" << endl;
}
if (input == "s")
{
outsideHouse();
}
if (input == "stats")
{
stats();
}
if (input == "help")
{
help();
}
else
{
cout << "Sorry I am not Siri I don't understand" << endl;
getline(cin, input);
}
break;
}
return 0;
}

You see different approaches of using functions in here,
thats how I would solve this.
You can focus on adding new questions in the main() part and doesn't have to write
all the if-requests over and over.
#include <iostream>
#include <string>
using namespace std;
void help();
void stats();
string check(string input,string n,string s, string w, string e)
{
string result;
if (input == "n"){
result = n;}
else if (input == "s"){
result = s;}
else if (input == "w"){
result = w;}
else if (input == "e"){
result = e;}
else if (input == "help"){
cout << "help" << endl;} //help()
else if (input == "stats"){
cout << "stats" << endl;} // stats()
else if (input == "exit"){
result = "exit";}
else
cout << "Sorry I am not Siri I don't understand. Try again" << endl;
return result;
}
string call()
{
string input;
cout << "Where do you want to go? n s w e" << endl;
getline(cin, input);
return input;
}
int main()
{
bool slope = false;
string input, result;
input = call();
result = check(input,"outside","dTable", "You just ran into a wall", "You sit on the sofa. Congratulations");
while (slope != true)
{
if(result == "house")//room1
{
cout << "You are in the house" << endl;
input = call();
result = check(input,"outside","dTable", "You just ran into a wall", "You sit on the sofa. Congratulations");
}
else if(result == "outside")//room2
{
cout << "You are outside"<< endl;
input = call();
result = check(input,"You just ran into a wall", "house","dTable", "You sit on the sofa. Congratulations");
}
else if(result == "dTable")//room3
{
cout << "You are dTable" << endl;
input = call();
result = check(input,"You just ran into a wall", "You sit on the sofa. Congratulations","outside","house");
} ///adding one room after another and connect it with each other
else if(result == "exit")
{
slope = true;
}
else
{
cout << result << endl;
input = call();
//some winning or loosing message here
}
}
return 0;
}

Related

Creating a Login and Register with username and password constraints and saving the data in a file. (C++)

I am a beginner at coding and learning C++. I just wrote a code that asks the user to log in, Register, or exit.
I thought doing it through functions would be easier. While checking for the constraints of the username and password for registration(referred to as "Rusr" and "Rpwd" here) the code I've written to check if lowercase, uppercase, and digits are not working. I tried to do it with character array as well but that didn't work. Would really appreciate some help with this.
Here's my code below for further reference:
#include <fstream>
#include <iostream>
#include <string.h>
using namespace std;
bool isvalidName(string Rusr)
{
if(Rusr.length() > 5 && Rusr.length() < 20) // length constraint
return true;
else
cout << "Invalid username" << endl;
{
for(int i = 0; i < Rusr.length(); i++) // check if digits are present
{
if(isdigit(Rusr[i]) == true)
return true;
if(true)
break;
else
cout << "Invalid username";
}
}
{
for(int i = 0; i < Rusr.length(); i++) // check for lowercase
{
if(islower(Rusr[i])) {
return true;
}
if(true)
break;
else
cout << "Invalid username";
}
}
{
for(int i = 0; i < Rusr.length(); i++) // check for uppercase
{
if(isupper(Rusr[i])) return true;
if(true)
break;
else
cout << "Invalid username";
}
}
}
int isvalidPwd(string Rpwd) {
{
if(Rpwd.length() > 8 && Rpwd.length() < 20)
return true;
else
cout << "Invalid password " << endl;
}
{
for(int i = 0; i < Rpwd.length(); i++) {
if(isdigit(Rpwd[i]) == true) return true;
if(true)
break;
else
cout << "Invalid password";
}
}
{
if(!((Rpwd.find("#") == string::npos) ||
(Rpwd.find("#") == string::npos) ||
(Rpwd.find("!") == string::npos) ||
(Rpwd.find("$") == string::npos) ||
(Rpwd.find("%") == string::npos) ||
(Rpwd.find("^") == string::npos) ||
(Rpwd.find("&") == string::npos) ||
(Rpwd.find("*") == string::npos) ||
(Rpwd.find("(") == string::npos) ||
(Rpwd.find(")") == string::npos) ||
(Rpwd.find("_") == string::npos) ||
(Rpwd.find("+") == string::npos) ||
(Rpwd.find("|") == string::npos) ||
(Rpwd.find(">") == string::npos) ||
(Rpwd.find("<") == string::npos) ||
(Rpwd.find("?") == string::npos) ||
(Rpwd.find("/") == string::npos) ||
(Rpwd.find("~") == string::npos) ||
(Rpwd.find(".") == string::npos) ||
(Rpwd.find(",") == string::npos)))
return true;
else
cout << "should contain special characters" << endl;
}
for(int i = 0; i < Rpwd.length(); i++) {
if(islower(Rpwd[i])) return true;
if(true)
break;
else
cout << "should contain lower case";
}
{
for(int i = 0; i < Rpwd.length(); i++) {
if(isupper(Rpwd[i])) return true;
if(true)
break;
else
cout << "Should contain upper case";
}
}
}
int main() {
string Lusr, Lpwd, Rusr, Rpwd, name, pwd;
while(1) {
cout << "___________________________________" << endl;
cout << "Chose 1 to Register or 2 to Login" << endl;
cout << "___________________________________" << endl;
cout << "1.Register" << endl;
cout << "2.Login" << endl;
cout << "3.Exit" << endl;
cout << "___________________________________" << endl;
int choice;
cin >> choice;
if(choice == 1) // register
{
ofstream of("register.txt");
if(!of.is_open()) {
cout << "file not exist" << endl;
}
do {
cout << "Username should contain capital,small letters and "
"numbers. "
<< endl;
cout << "______________________________________" << endl;
cout << "Enter new username:" << endl;
cin.ignore();
getline(cin, Rusr);
isvalidName(Rusr);
} while(isvalidName(Rusr) == true);
do {
cout << "Password should contain capital,small letters,special "
"characters and numbers. "
<< endl;
cout << "_______________________________________" << endl;
cout << "Enter new passsword:" << endl;
getline(cin, Rpwd);
isvalidPwd(Rpwd);
} while(isvalidPwd(Rpwd) == true);
of << Rusr;
of << '\n';
of << Rpwd;
of.close();
}
else if(choice == 2) {
ifstream f("register.txt");
if(!f.is_open()) {
cout << "file not open" << endl;
}
getline(f, name, '\n');
getline(f, pwd, '\n');
f.close();
cout << "Enter username:" << endl;
cin.ignore();
getline(cin, Lusr);
cout << "Enter passsword:" << endl;
getline(cin, Lpwd);
if(Lpwd == pwd && Lusr == name) {
cout << "Welcome " << Lusr << endl;
;
break;
}
cout << "Wrong name and password" << endl;
}
else if(choice == 3) {
return 1;
} else {
cout << "Invalid input!Try again." << endl;
}
}
return 0;
}
With your code, some of your logic is wrong. When you say this
if(Rusr.length() > 5 && Rusr.length() < 20) // length constraint
return true;
else
cout << "Invalid username`enter code here`" << endl;
Any string that is between 5 and 20 characters will be accepted as a valid username. To fix this, you need to go through all your requirements, then return true. If any of the requirements fail, return false. This makes it so that the only way that the username will be valid is if it has already passed all the requirements.
bool isvalidName(string Rusr)
{
if(Rusr.length() < 5 || Rusr.length() > 20) // length constraint
{
std::cout << "invalid username length" << std::endl;
return false;
}
for(int i = 0; i < Rusr.length(); i++) // check if digits are present
{
if(isdigit(Rusr[i])) // if a digit is present, continue
{
break;
}
if(i == Rusr.length() - 1) // No digits were found
{
return false;
}
}
for(int i = 0; i < Rusr.length(); i++) // check for lowercase
{
if(islower(Rusr[i])) {
break;
}
if(i == Rusr.length() - 1) // No lowercase letters were found
{
cout << "Invalid username";
return false;
}
}
for(int i = 0; i < Rusr.length(); i++) // check for uppercase
{
if(isupper(Rusr[i]))
{
break;
}
if(i == Rusr.length() - 1) // No uppercase letters were found
{
cout << "Invalid username";
return false;
}
}
return true;
}
This way, the only way you return true is if it gets past all the constraints.
For the password, you would want to follow this model and adjust for those constraints.
Some other things to watch out for are the extra braces you have included. Best practice is to not change the scope further in than you need to, so you should avoid the braces in almost every case.
Both your functions fail to return the value you've declared that they should return in all branches, so your program has undefined behavior.
Also, the logic is flawed. Example:
bool isvalidName(string Rusr) {
if(Rusr.length() > 5 && Rusr.length() < 20) // length constraint
return true;
else
cout << "Invalid username`enter code here`" << endl;
// .. the rest ...
}
Here you check that the length is [6, 19] characters long - and return true; - that's all it takes to get Rusr approved. None of the other tests in your function will be executed if the name has an approved length.
Your code is riddled with similar mistakes.
for(int i = 0; i < Rusr.length(); i++) // check if digits are present
{
if(isdigit(Rusr[i]) == true) return true;
The first digit you encounter makes isvalidName return true - so now you have a name with an invalid length that contains a digit - approved!
Similar issue below. A name with an illegal length, without digits, that contains a lowercase letter is immediately approved:
for(int i = 0; i < Rusr.length(); i++) // check for lowercase
{
if(islower(Rusr[i])) {
return true;
And finally, if a name with an illegal length, without digits and without lowercase letters contains an uppercase letter, it's approved:
for(int i = 0; i < Rusr.length(); i++) // check for uppercase
{
if(isupper(Rusr[i])) return true;
If none of the above applies - you don't return anything (causing undefined behavior).
Your second function follows this pattern.

Tic Tac Toe , Why am I getting the error non standard syntax use & to create a pointer to a member [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
here is my main . I get the error for the part I am checking whether the game had a winner or not. the errors are referring to the if parts where i wanna check the returned data from chkwin method
#include<iostream>
#include<string>
#include "TicTacToe.h"
using namespace std;
int main()
{
string choice = "";
string name1 = "";
string name2 = "";
string change = "";
int choice_num;
TicTacToe game;
cout << "Welcome to TicTacToe World!\n"
<< "In order to Start Please Enter the name of the first player\n\n";
getline(cin, name1);
cout << "\nGreat, Now Please Enter the name of the second player\n\n";
getline(cin,
name2);
cout << "\nAwesome Let's Get Started!\n";
do
{
cout << "\nPlease choose what do you want to do by entering the number of your choice\n"
<< "1.Start the game.\n"
<< "2.Change the names.\n"
<< "3.View Scores\n"
<< "4.Exit the Game :(\n\n";
getline(cin, choice);
if (choice == "1")
{
for (int i = 1; 1 <= 9; i++)
{
if (i % 2 != 0)
{
cout << "It's " << name1 << " Turn. Please Make Your move.";
cin >> choice_num;
cin.ignore();
game.setMove(choice_num, 1);
if (game.chkWin == 1)
{
cout << name1 << " has won this Game!";
}
else if (game.chkWin == -1)
{
cout << name1 << " has won this Game!";
}
else if (game.chkWin == 0)
{
cout <<"The Game is a Draw! ";
}
}
else
{
cout << "It's " << name1 << " Turn. Please Make Your move.";
cin >> choice;
cin.ignore();
game.setMove(choice_num, 2);
if ( 1 == game.chkWin)
{
cout << name1 << " has won this Game!";
}
else if (game.chkWin == -1)
{
cout << name1 << " has won this Game!";
}
else if (game.chkWin == 0)
{
cout << "The Game is a Draw! ";
}
}
}
}
else if (choice == "2")
{
do
{
cout << "\nwhich player do you want its name to be changed? (Enter 1 for the first, 2 for the second and 3 for both)\n";
getline(cin, change);
if (change == "1")
{
cout << "\nPlease Enter the new name for the player one.\n";
getline(cin, name1);
}
else if (change == "2")
{
cout << "\nPlease Enter the new name for the player two.\n";
getline(cin, name2);
}
else if (change == "3")
{
cout << "\nPlease Enter the new name for the player one.\n";
getline(cin, name1);
cout << "\nPlease Enter the new name for the player two.\n";
getline(cin, name2);
}
else
{
cout << "\nPlease Enter a Valid Choice.\n";
}
} while (change != "1" && change != "2" && change != "3");
}
else if (choice == "3")
{
cout << "\n" << game.getResults(name1, name2);
}
else if (choice != "4")
{
cout << "\nPlease Enter a Correct number\n";
}
} while (choice!= "4");
cout << "\nFinal Results are: \n\n"
<< game.getResults(name1, name2);
cout << "\nThank you for using our program. Hope to see You Again. Bye Bye!!\n";
system("Pause");
return 0;
}
my class
#include<iostream>
#include<string>
using namespace std;
#ifndef TICTACTOE_H
#define TICTACTOE_H
class TicTacToe
{
private:
const static int SIZE = 3;
int table[SIZE][SIZE];
int results[SIZE];
int winner = 2;
public:
TicTacToe();
void setMove(int , int );
int chkWin();
string getResults(string , string );
};
#endif
here is my methods declaration:
#include<iostream>
#include<string>
#include "TicTacToe.h"
using namespace std;
TicTacToe::TicTacToe()
{
for (int i = 0; i < SIZE; i++)
{
results[i] = 0;
for (int j = 0; j < SIZE; j++)
{
table[i][j] = 0;
}
}
}
void TicTacToe::setMove(int place, int player)
{
int field = place;
if (field == 1)
{
if (table[0][0] == 0)
{
table[0][0] = player;
}
else
{
cout << "\nYou cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 2)
{
if (table[0][1] == 0)
{
table[0][1] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 3)
{
if (table[0][2] == 0)
{
table[0][2] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 4)
{
if (table[1][0] == 0)
{
table[1][0] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 5)
{
if (table[1][1] == 0)
{
table[1][1] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 6)
{
if (table[1][2] == 0)
{
table[1][2] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 7)
{
if (table[2][0] == 0)
{
table[2][0] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 8)
{
if (table[2][1] == 0)
{
table[2][1] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
else if (field == 9)
{
if (table[2][2] == 0)
{
table[2][2] = player;
}
else
{
cout << "You cannot make this move this place is already occupied.Please choose another Field\n";
cin >> field;
cin.ignore();
setMove(field, player);
}
}
}
int TicTacToe::chkWin()
{
for (int i = 0; i < SIZE; i++)
{
if (table[i][0] == table[i][1] && table[i][0] == table[i][2])
{
if (table[i][0] == 1)
{
results[0] += 1;
winner = 1;
}
else if (table[i][0] == 2)
{
results[2] += 1;
winner = -1;
}
}
else if (table[0][i] == table[1][i] && table[0][i] == table[2][i])
{
if (table[0][i] == 1)
{
results[0] += 1;
winner = 1;
}
else if (table[0][i] == 2)
{
results[2] += 1;
winner = -1;
}
}
}
if ((table[0][0] == table[1][1] && table[0][0] == table[2][2]) || (table[0][2] == table[1][1] && table[0][2] == table[2][0]))
{
if (table[1][1] == 1)
{
results[0] += 1;
winner = 1;
}
else if (table[1][1] == 2)
{
results[2] += 1;
winner = -1;
}
}
else
{
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
if(table[i][j] == 0)
{
winner = 2;
}
}
}
results[1] += 1;;
return winner;
}
}
string TicTacToe::getResults(string name1, string name2)
{
return ( name1 + " : " + to_string(results[0]) + "\n"
+ "Draws : " + to_string(results[1]) + "\n"
+ name2 + " : " + to_string(results[2]) + "\n");
}
Compareing functions with integers doesn't make sense. You have to use () operator to call functions like this:
if (game.chkWin() == 1)
instead of
if (game.chkWin == 1)
Poor:
game.setMove(choice_num, 1);
if (game.chkWin == 1)
{
cout << name1 << " has won this Game!";
}
else if (game.chkWin == -1)
{
cout << name1 << " has won this Game!";
}
else if (game.chkWin == 0)
{
cout <<"The Game is a Draw! ";
}
Better:
game.setMove(choice_num, 1);
switch (game.chkWin()) {
case 1:
cout << name1 << " has won this Game!";
break;
case -1:
cout << name1 << " has won this Game!";
break;
case 0:
cout <<"The Game is a Draw! ";
break;
}
The basic problem is using "==" with function game.chkWin, instead of with the result of function game.chkWin().
But in cases like this (pun intended) a "switch()" block is probably more readable and better style than multiple "if/else" statements.
'Hope that helps...

Calling a member of an array in an if/else statement

I'm trying to write an if/else statement that says 'if the the random question chosen is the first in the array do this ....' etc for all the members of the array. However it is defaulting every question chosen as the first member of the array and carrying out that action. How can I get it to separate that?
if (choice == 1)
{
enum fields{ QUESTS, ANS_1, ANS_2, ANS_3, ANS_4, NUM_FIELDS };
string QUEST[NUM_QUEST][NUM_FIELDS] =
{
{ "What course is this?\n", "A)C++\n", "B)DID\n", "C)Intro to Game\n", "D)Yoga" },
{ "Who am I?\n", "A)Bill\n", "B)Nye\n", "C) 24601\n", "D)No one\n" },
{ "Are you actually reading this?\n", "A) Yes\n", "B)No\n", "C)Maybe\n", "D)Who wants to know?\n" },
{ "Will this program work?\n", "A)Of course it will!\n", "B)It might\n", "C)Are you kidding me?\n", "D)Gods only know." },
{ "Where would I rather be?\n", "A)Home\n", "B)Europe\n", "C)Anywhere but here\n", "D)All of the above\n" }
};
srand(static_cast<unsigned int>(time(0)));
int randomQuest = (rand() % NUM_QUEST);
string question = QUEST[randomQuest][QUESTS];
cout << question;
string printAns1 = QUEST[randomQuest][ANS_1];
string printAns2 = QUEST[randomQuest][ANS_2];
string printAns3 = QUEST[randomQuest][ANS_3];
string printAns4 = QUEST[randomQuest][ANS_4];
cout << printAns1;
cout << printAns2;
cout << printAns3;
cout << printAns4;
cout << "\nAnswer:";
string answer;
cin >> answer;
//PROBLEM IS HERE. KEEPS DEFAULTING TO THIS IF STATEMENT AND IGNORING THE REST SO THAT IT THINKS THE ANSWER IS ALWAYS A
if (question == QUEST[randomQuest][0])
{
if (answer == "A")
{
cout << "Correct. Proceed.";
}
else if (answer != "A")
{
cout << "Failure. Leave. Or, you know, try again.";
}
}
else if (question == QUEST[randomQuest][1])
{
if (answer == "C")
{
cout << "Correct. Proceed.";
}
else if (answer != "C")
{
cout << "Failure. Leave. Or, you know, try again.";
}
}
else if (question == QUEST[randomQuest][2])
{
if (answer == "D")
{
cout << "Correct. Proceed.";
}
else if (answer != "D")
{
cout << "Failure. Leave. Or, you know, try again.";
}
}
else if (question == QUEST[randomQuest][3])
{
if (answer == "C")
{
cout << "Correct. Proceed.";
}
else if (answer != "C")
{
cout << "Failure. Leave. Or, you know, try again.";
}
}
else if (question == QUEST[randomQuest][4])
{
if (answer == "D")
{
cout << "Correct. Proceed.";
}
else if (answer != "D")
{
cout << "Failure. Leave. Or, you know, try again.";
}
}
}
You did not post the full source, so I just posted an example of how I would do this. Even thought it has a few more lines, its much more readable IMHO.
#include <stdio.h>
#include <vector>
#include <string>
struct Question
{
unsigned char answer;
std::string title;
std::vector<std::string> options;
};
int main()
{
std::vector<Question> questions;
// Define the questions
Question questionOne;
Question questionTwo;
Question questionThree;
Question questionFour;
Question questionFive;
questionOne.answer = 'c';
questionOne.title = "What course is this?";
questionOne.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionOne.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionOne.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionOne.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionTwo.answer = 'a';
questionTwo.title = "Who am I?";
questionTwo.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionTwo.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionTwo.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionTwo.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionThree.answer = 'b';
questionThree.title = "Are you actually reading this?";
questionThree.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionThree.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionThree.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionThree.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFour.answer = 'c';
questionFour.title = "Will this program work?";
questionFour.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFour.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFour.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFour.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFive.answer = 'd';
questionFive.title = "Where would I rather be?";
questionFive.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFive.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFive.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
questionFive.options.push_back("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
// Save them
questions.push_back(questionOne);
questions.push_back(questionTwo);
questions.push_back(questionThree);
questions.push_back(questionFour);
questions.push_back(questionFive);
// Change to a random question accordingly
for (auto& question : questions)
{
// Show question title
std::cout << question.title << std::endl;
// Show question options
for (auto& option : question.options)
{
std::cout << option << std::endl;
}
// Get the user input accordingly
unsigned char userInput = 0;
// Validate user input
if (userInput == question.answer)
{
std::cout << "Congratulations! Next question coming up..." << std::endl;
}
else
{
std::cout << "Wrong answer. Next question coming up..." << std::endl;
}
}
return 0;
}

C++ File editing without deleting.other information

I am programming a stock trading program.
For this function, I need to change the balance in a specific account, but whenever I output back to the file, it updates the balance for one account and deletes everyone else.
Source Code:
void Buying()
{
ifstream Companies;
ifstream Account;
Account.open("Account.txt");
{
int ID;
double cash;
string sym;
ifstream Account;
Account.open("Account.txt");
//Check for errord
if (Account.fail())
{
cout << "Failed" << endl;
exit(1);
}
account S_accounts;
for (int i = 0; i < 5; i++)
{
Account >> S_accounts.id[i] >> S_accounts.cash[i];
}
cout << "Please enter your last 4 digits of your ID: ";
do
{
cin >> ID;
cout << endl;
switch (ID)
{
case 1111:
cash = S_accounts.cash[0];
break;
case 2222:
cash = S_accounts.cash[1];
break;
case 3333:
cash = S_accounts.cash[2];
break;
case 4444:
cash = S_accounts.cash[3];
break;
case 5555:
cash = S_accounts.cash[4];
break;
default:
cout << "ID number is invalid. please try again." << endl;
}
break;
} while (ID != 1111 || ID != 2222 || ID != 3333 || ID != 4444 || ID != 5555);
if (cash > 36.80)
{
cout << "You have $" << cash << " what stock would you like to purchase?" << endl;
listing();
cout << endl;
cout << "Type the stock symbol of the company that you would like to purchase." << endl;
cin >> sym;
double price;
int number_of_stock;
double total;
int i = 0;
while (i < 7)
{
Stock S_companies;
Companies >> S_companies.price[i];
i++;
}
//Stock S_companies;
if (sym == "AAPL" || sym== "aapl")
{
price = 450.00;
}
else if (sym == "BA" || sym == "ba")
{
price = 75.50;
}
else if (sym == "INTC" || sym == "intc")
{
price = 22.30;
}
else if (sym == "RMBS" || sym == "rmbs")
{
price = 5.55;
}
if (sym == "SIRI" || sym == "siri")
{
price = 3.15;
}
if (sym == "SWKS" || sym == "swks")
{
price = 25.35;
}
if (sym == "XLNX" || sym == "xlnx")
{
price = 36.80;
}
cout << "How many stock(s) would you like to buy?" << endl;
cin >> number_of_stock;
total = number_of_stock*price;
if (cash > total)
{
account S_account;
ofstream Oaccount;
Oaccount.open("Account.txt");
if (Oaccount.fail())
{
"Failed to open the file.";
}
I know this is where I need to edit but I am absolutely clueless on what to do so it only changes the account balance for the person that logged in using their ID.
if (ID == 1111)
{
Oaccount << S_accounts.id[0] << '\t' << '\t' << S_accounts.cash[0] - total;
}
Oaccount.close();
}
else
cout << "You do not have enough money.";
}
else
{
cout << "Sorry, you do not have enough money in your account.";
exit(1);
}
Account.close();
}
}
Im not debugging your code.But This is how you update/modify an entry...
let number be the value with which you want to find an account...lets say you want to change his name to newname...
while(!file.eof())
{
if(obj.number==given_value)
{
file.tellg(pos);
{
//modify values here like..
strcpy(obj.name,newname);
file.seekg(pos);
file.write((char*)&obj,sizeof(obj));
}
}
}

invalid input by the user

hey guys so this is my program, I need to notify the user that if hhe/she enters a letter other than w d b or w that is an invalid request. what ive done so far does this, but when i input a number to the dollars_withdraw or dollars_deposit or account_balance the program will do the transaction but also add the "invalid request" before going back to main loop. how do i change it so the program wont do that for numerical inputs for the withdraw deposit and balance?:
// Atm machine.cpp : Defines the entry point for the console application.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
char user_request;
string user_string;
double account_balance, dollars_withdraw, dollars_deposit;
account_balance = 5000;
while(account_balance >0)
{
cout << "Would you like to [W]ithdraw, [D]eposit, Check your [b]alance or [Q]uit?"
<< endl;
cin >> user_string;
user_request= user_string[0];
if(user_request == 'w' || user_request== 'W')
{
cout << "How much would you like to withdraw?" << endl;
cin >> dollars_withdraw;
if (dollars_withdraw > account_balance || dollars_withdraw <0)
cout << "Invalid transaction" << endl;
else
account_balance = account_balance - dollars_withdraw;
cout << "Your new balance is $" << account_balance << endl;
}
if (user_request == 'd' || user_request== 'D')
{
cout << "How much would you like to deposit?" << endl;
cin >> dollars_deposit;
if (dollars_deposit <0)
cout << "Invalid transaction" << endl;
else
account_balance= account_balance + dollars_deposit;
cout << "Your new balance is $" << account_balance << endl;
}
if(user_request == 'b' || user_request == 'B')
{
account_balance= account_balance;
cout << "Your available balance is $" << account_balance << endl;
}
if(user_request == 'q' || user_request == 'Q')
break;
else
cout << "Invalid request " << endl;
}
cout << "Goodbye" << endl;
return 0;
}
Sure it does. Your code says:
If it is a 'w' do something
...
If it is a 'q' do something, else yell "invalid"
So if the user does not enter a 'q', the last 'else' block will always be executed. Either use else if throughout or change your code to use a switch statement:
// Either:
if (user_request == ...) {
...
} else if (user_request == ...) {
...
} else {
std::cout << "invalid";
}
// Or (better, faster):
switch (user_request) {
case 'q':
case 'Q':
...
break;
...
default:
std::cout << "Invalid request";
}
A third option would be to use continue:
while (...) {
user_request = ...
if (user_request == 'w' ...) {
...
continue; // In this iteration, no other code within the while loop is executed.
}
if (...)
...
}
This is a bad programming practice. Please use Switch Case for what you need to achieve. And put a "break" statement after every case branch.
chain your if statements into if, else-if, else-if, ..., else.
else statements only "know of" the if statement immediately previous. For example:
if (myNumber == 0)
{
// Triggers when myNumber is zero.
}
if (myNumber == 1)
{
// Triggers when myNumber is one.
}
else
{
// Triggers when myNumber is not one.
}
This can be fixed with else if statements. In your case it would look something like this:
if (user_request == w)
{
// ...
}
else if (user_request == d)
{
// ...
}
// ...
else cout << "Invalid request.";
In my old CS class, I'd do things like this:
string user_string;
do {
if(user_string) cout << "Enter a valid value!" << endl;
cin >> user_string;
} while(user_string != "w" && user_string != "d");
You need to use else if as follows:
if(user_request == 'w' || user_request== 'W')
{
...
} else if(user_request == 'd' || user_request== 'D')
{
....
} else if(user_request == 'b' || user_request== 'B')
{
.....
} else if(user_request == 'q' || user_request== 'Q')
{
...
} else
{
// Invalid request
}