reuses "rechnung()" even though it shouldn't - c++

#include <iostream>
#include "funktionen.h"
using namespace std;
int rechnung()
{
cout << "Please choose the operator you want to calculate with" << endl;
int eingabe1;
int eingabe2;
int eingabe;
int dummy;
char zeichen;
char again;
cin >> zeichen;
cout << endl << "1. Eingabe: ";
cin >> eingabe1;
cout << endl << "2. Eingabe: ";
cin >> eingabe2;
switch (zeichen)
{
case '+':
eingabe=eingabe1 + eingabe2;
break;
case '-':
eingabe=eingabe1 - eingabe2;
break;
case '*':
eingabe=eingabe1 * eingabe2;
break;
case '/':
eingabe=eingabe1 / eingabe2;
break;
}
cout << endl << "Das Ergebnis ist | " << eingabe << " | " << endl << endl;
cout << "Wanna calculate again? ";
cin >> again;
while(again=='Y')
{
rechnung();
}
return 0;
}
So this is my code in an implementation file. My problem is, that the main program always loops the whole "rechnung()" function even though I don't type "Y" into the console once it asks for it. In the beginning, when I type something else than "Y", then the console closes (as it shall) but if I do a calculation, type "Y", do another calculation and type "k" for example, it also starts from the beginning of "rechnung()". Why does it do so? I mean I told him that he shall only recall the "rechnung()" if the character input is "Y".

Consider this maybe simpler example:
void foo() {}
void bar() {
char again;
// ... do something
std::cin >> again;
while(again=='Y') {
foo();
}
}
Inside the loop the value of again never changes, so there is an infinite loop. However, your code goes one step further by calling the function recursively. Strongly simplified you have:
void bar() {
// .. do something
while (true) {
bar();
}
}
ie bar is calling itself again and again and never returns. You put the loop at the wrong place. You could write it like this
void bar() {
char again = 'Y';
while (again == 'Y') {
// .. do something
std::cout << "repeat?";
std::cin >> again;
}
}

Related

How to check if input is valid and keep asking for input if it's not

Can anybody please explain why this while loop is not working properly?
#include <iostream>
using namespace std;
void ask_user(int a, int b){
char choice = ' ';
while(choice != 'q' && choice != 'a' && choice != 's' && choice != 'm'){
cout << "choose operation" << endl;
cout << "a to add, s to subtract, m to multiply and q to quit" << endl;
cout << "----------------------------" << endl;
cin >> choice;
switch(choice){
case 'a' : cout << "a + b = " << a + b;
break;
case 's' : cout << "a - b = " << a + b;
break;
case 'm' : cout << "a * b = " << a + b;
break;
case 'q' : break;
default: cout << "please Enter a valid choice " << endl;
}
}
}
int main(){
ask_user(7, 9);
return 0;
}
If I enter p for exemple which is not valid then it works fine and asks for valid input again,
but if I enter pp that's when it starts bugging and prints the message twice. If I enter ppp it
prints three times etc...
First thing, you have a misunderstanding of how switch works. Each case must end with break statement so that the following one won't get executed.
Which means that a break will break the switch, not the while.
But the main issue is that the logic of your program is wrong.
You should not loop over the validity of the given input, let the switch statement handle that in the default clause.
Instead you should loop over a flag that will be set when the user press the q key.
So considering you have the following functions defined to respectively display the menu and ask for the operands to operate on (defined for code readability):
void display_menu(char & choice)
{
std::cout << "Operation:\na: Addition\nm: Multiplication\ns: Substraction\nq: Quit\n";
std::cin >> choice;
}
void ask_operands(int & a, int & b)
{
std::cout << "\na ?";
std::cin >> a;
std::cout << "\nb ?";
std::cin >> b;
std::cout << '\n';
}
The logic of your code can be then rewritten as:
int main()
{
bool quit = false;
char choice;
int a, b;
ask_operands(a, b); // Ask the user which operands to use
while(!quit) // loop over the flag
{
display_menu(choice);
switch(choice)
{
case 'a': std::cout << (a+b);
break;
case 'm': std::cout << (a*b);
break;
case 's': std::cout << (a-b);
break;
case 'q': std::cout << "Exiting...";
quit = true; // Set the flag to false
break;
default: std::cout << "Invalid choice, try again."; //Here you handle the invalid choices (i.e. let the loop iterate again)
}
std::cout << '\n';
}
return 0;
}
Live example
Note: If you want the user to be able to change the value of the operands at each iteration, just move the ask_operands(a, b); call inside the loop.

Exit from switch C++

#include <iostream>
#include <string>
#include <vector>
#include "Player.h"
using namespace std;
void PlayerMenu();
int main() {
int z;
cout << "Please press 0 to see the PLayers Menu. " << endl;
cin >> z;
while (z == 0) {
PlayerMenu();
}
cout << " Now You're Functional Lets get started. ";
};
void PlayerMenu()
{
char ch;
int num;
do {
system("cls");
cout << "\n\n\n\t Player Menu";
cout << "\n\n1 Wallet Balance ";
cout << "\n\n2 Player Invetory";
cout << "\n\n3 To Exit";
cin >> ch;
system("cls");
switch (ch)
{
case '1':
cout << "Your Balance at the moment is ..."<<endl;
cout << "\n";
Bank();
break;
//Show Wallet Balance
case '2':
cout << "Here is your Inventory"<<endl;
cout << "\n";
break;
//Show Inventory
case '3':
cout << " Bye.\n";
break;
//exit i'VE TRIED bREKA BUT it will not go back to the main source code or main method
}
cin.ignore();
cin.get();
} while (ch != '3');//If not 1 or 2 or 3 will ignore it
}
I tried break statements, but the break method will not exit to the main method and run the last following statement. I would like to also run methods inside of the case to case so when a player is selecting 1 it will show the balance of the player. Also when the player inputs a value of 2 it will show a vector of weapons bought.
Use return instead of break to exit from the current function. You then don't need the while (ch != '3'). Instead, you can just use an infinite loop:
while (true) {
// ...
case '3':
cout << " Bye.\n";
return;
}
cin.ignore();
cin.get();
}
You can also use for (;;) instead of while (true), but that's just a stylistic choice.
Also, don't call PlayerMenu() in a loop in main. Just do:
int main()
{
int z;
cout << "Please press 0 to see the PLayers Menu. " << endl;
cin >> z;
if (z == 0) {
PlayerMenu();
}
cout << " Now You're Functional Lets get started. ";
}
break in this context exits the switch. If you wish to exit the function, you will need to return instead.
Your PlayerMenu() function is exiting just fine. The problem is in main():
while (z == 0) {
PlayerMenu();
}
There is nothing in the loop that modifies z, so it never exits. It just keeps going back to the menu forever.
I don't know if you intended to loop there or just test it with an if.

ifstream only printing first line in array

void adding();
void print();
void end();
int counter = 0;
int main()
{
char choice;
cout << "What do you want to do?" << endl;
cout << "a = add a student, p = print the student list, e = exit function" << endl;
cin >> choice;
switch (choice) {
case 'a':
adding();
break;
case 'p':
print();
break;
case 'e':
end();
break;
default:
cout << "That is not a valid option.";
break;
}
}
void adding()
{
ofstream outFS;
outFS.open("myoutfile.txt", fstream::app);
int i = 0;
string name[100]; string amount[100]; string grades[100];
for (i = 0; i < 1; i++) {
cout << "What is the name of the student?";
cin >> name[i];
outFS << name[0] << ' ';
cout << "How many exercises has the student completed?";
cin >> amount[i];
outFS << amount[0] << ' ';
cout << "What grade did the student get?";
cin >> grades[i];
outFS << grades[0] << ' ';
counter++;
}
outFS.close();
main();
}
void print()
{
ifstream inFS;
inFS.open("myoutfile.txt");
string name;
inFS >> name;
int amount;
inFS >> amount;
int grades;
inFS >> grades;
inFS.close();
cout << name << ' ' << amount << ' ' << grades << endl;
main();
So when I use the "adding" function it works fine and adds it to the file. When I add the more than one student the file still shows it but when I print within the console it only prints out the first student and their info. How do I get it to show the entire array in the console? I tried to use a counter variable but it is not helping
What you are missing is the loop keywords (the various incarnations of for and while).
Making your own loop by doing this:
void a()
{
// Do stuff
b();
}
void b()
{
// Do other stuff
a();
}
Is really not a good idea since it will just throw more and more calls on the stack, and eventually make the stack run out of space (which will crash the program). Replacing one of those functions with main() is even worse, because main() is a special function that you really are not allowed to call yourself.
Instead do something like this:
int main()
{
char choice;
bool running = true;
while (running)
{
cout << "What do you want to do?" << endl;
cout << "a = add a student, p = print the student list, e = exit function" << endl;
cin >> choice;
switch (choice) {
case 'a':
adding();
break;
case 'p':
print();
break;
case 'e':
// end(); Dunno what this does. Is it just an empty function that will finally end the infinite stack of calls?
// I am replacing it with setting the loop variable to false, which will stop the loop
running = false;
break;
default:
cout << "That is not a valid option.";
break;
}
}
}
Then remove all calls to main() from the rest of your code.
As for your print() function, again your problem is the lack of loops. Your current code opens the file, reads the first line, prints the line, then closes the file and calls main. Then the next time print() is called it again opens the file, reads the first line, etc.
What you need is a loop that reads all the lines before closing the file again. Something like this should do the trick:
void print()
{
ifstream inFS;
inFS.open("myoutfile.txt");
string name;
int amount;
int grades;
while (inFS >> name >> amount >> grades)
{
cout << name << ' ' << amount << ' ' << grades << endl;
}
inFS.close();
}
However, all of this is pretty basic C++ that should have been covered in whatever book you are using to learn C++. And if you do not have a C++ book to learn from, then I strongly recommend that you get one - it will be only get harder to learn if you constantly get stuck on basic stuff.

Some kind of 'goto' function for C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
#include <iostream>
using namespace std;
int main()
{
float a, b, result;
char operation, response;
cin >> a >> operation >> b;
switch(operation)
{
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
default:
cout << "Invalid operation. Program terminated." << endl;
return -1;
}
// Output result
cout << "The result is " << result << endl;
system("sleep 200");
cout << "Do you want to make another opertaion? (Y/N)" << endl;
cin >> response;
if(response=='Y')
{
here
}
else if(response=='N')
{
cout << "The program will now close" << endl;
system("sleep 500");
return -1;
}
return 0;
}
Where the word 'here' is written, I want to insert a code that gets you to the beggining of the code.
You can use the loop do... while(condition)
Like :
do{
cin >> a >> operation >> b;
switch(operation)
{
...
}
// Output result
cout << "The result is " << result << endl;
system("sleep 200");
cout << "Do you want to make another opertaion? (Y/N)" << endl;
cin >> response;
}while(response=='Y');
If the response isn't 'Y' the loop ends, if it is the loop begin again
All though goto is highly frowned upon in C++, it does exist.
Much like assembly, your put a label in your code and then tell it to 'jump' there using goto. However, the same way jump works in assembly, this may break you out of all loops to the point that you jump to.
#include <iostream>
using namespace std;
int main()
{
label:
float a, b, result;
char operation, response;
cin >> a >> operation >> b;
//condensed for neatness
// Output result
cout << "The result is " << result << endl;
system("sleep 200");
cout << "Do you want to make another opertaion? (Y/N)" << endl;
cin >> response;
if(response=='Y')
{
goto label;
}
else if(response=='N')
{
cout << "The program will no`enter code here`w close" << endl;
system("sleep 500");
return -1;
}
return 0;
}
What most people would do is use a do{}while(condition==true) loop or just an infinite loop while(true).
For this 'neater' code, what you would do is
#include <iostream>
using namespace std;
int main()
{
do{
float a, b, result;
char operation, response;
cin >> a >> operation >> b;
//condensed for neatness
// Output result
cout << "The result is " << result << endl;
system("sleep 200");
cout << "Do you want to make another opertaion? (Y/N)" << endl;
}while(cin.get() == 'Y');
cout << "The program will no`enter code here`w close" << endl;
system("sleep 500");
return -1;
return 0;
}
If this is being called from another location, I would highly recommend using do while rather than goto, as it can cause issues.
The only real problem with goto is that it's not elegant and makes code confusing to read. You should use loops and returns where possible, and only use goto if you see no other way to make this work optimally.

Bank System not working

For some reason my bank script isn't working. More specifically, the search() does not work. I kind of understand why it doesn't, probably because of if(obj.returnId() == n), but I have no clue how to fix it. When I search an account, it will only allow me to find the last account made, not any of the previous ones. Here is my code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <string.h>
#include <fstream>
#include <Windows.h>
#include <conio.h>
using namespace std;
bool loop = true;
class account
{
int id;
char name[40];
char password[40];
public:
void getData()
{
cout << "\nEnter your name: ";
cin >> name;
cout << "\nEnter ID: ";
cin >> id;
cout << "\Enter pass: ";
cin >> password;
}
void showData()
{
cout << "\nName: ";
puts(name);
cout << "\nID: " << id;
cout << "\n";
}
int returnId()
{
return id;
}
};
void createAccount()
{
account obj;
ofstream fileCreate;
fileCreate.open("accounts.dat", ios::binary|ios::app);
obj.getData();
fileCreate.write((char*)&obj,sizeof(obj));
fileCreate.close();
}
void display()
{
account obj;
ifstream fileRead;
fileRead.open("accounts.dat", ios::binary);
while(fileRead.read((char*)&obj, sizeof(obj)))
{
obj.showData();
}
fileRead.close();
}
void search(int n)
{
account obj;
ifstream fileRead;
fileRead.open("accounts.dat", ios::binary);
while(fileRead.read((char *) &obj, sizeof(obj)) );
{
fileRead.seekg(0,ios::beg);
if(obj.returnId() == n)
{
obj.showData();
}
else {
cout << "\nUser not foud!\n";
}
}
fileRead.close();
}
void main()
{
cout << "Welcome to the Bank.\n\n";
while (loop==true)
{
char choice[10];
cout << "Please select an option:\n";
cout << "------------------------------------------------\n";
cout << "(a)Log into an account\n(b)Create an account\n(s)Search an account\n(e)Exit\n";
cout << "------------------------------------------------\n";
cout << "Choice: ";
cin >> choice;
choice[0] = tolower(choice[0]);
cout << "\n------------------------------------------------\n\n";
switch (choice[0])
{
case 'a':
display();
break;
case 's':
int n;
cout << "Enter the ID of the account: ";
cin >> n;
search(n);
break;
case 'b':
createAccount();
break;
case 'e':
loop = false;
break;
default:
system("CLS");
cout << "The option \"" << choice[0] << "\" is invalid.\n\n\n\n";
break;
}
};
cout << "\n\n\n";
cout << "Click anything to exit.";
getch();
}
Your problem is the semicolon at the end of this line:
while(fileRead.read((char *) &obj, sizeof(obj)) );
That makes this loop have an empty body. So you basically read the whole file and throw away the results, except for the last entry.
get rid of this also:
fileRead.seekg(0,ios::beg);
I don't know why you need that, it would only make you read the first entry over and over.
The other error is that you should only say 'User not found' when you've tested all the accounts and they all failed. Your loop (when you've removed the semi-colon) is saying 'User not found' after every failed test.
You probably don't find the entry you are looking for because each time you have read an entry from the file, you reset the position to the beginning. This means that your loop will run forever, reading the same entry over and over again and never finding the entry you search for.
the seek might be the problem:
while(fileRead.read((char *) &obj, sizeof(obj)) ) //;
{
// seek to start?
//fileRead.seekg(0,ios::beg);
...
}
have a look at http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html
aside, use
cout << "text" << endl;
for platform-agnostic newlines.