File access not working - c++

I am watching Bucky's tutorials on C++. He made a program and i did exactly as he did but i cannot get the list to work. I can get the txt file to view the objects on a separate program but this program just doesn't wanna view anything. It works and compiles okay but nothing on the screen once a choice input is entered. Selecting 4 does exit the program but the 1,2,3 options don't bring up anything at all.
Here's the video explaining the program: https://www.youtube.com/watch?v=86rBqzYIbjA&index=68&list=PLAE85DE8440AA6B83#t=3.934331
My code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int getUserData();
void display(int x);
int main(){
int userdata;
userdata = getUserData();
while(userdata =! 4){
switch(userdata){
case 1:
display(1);
break;
case 2:
display(2);
break;
case 3:
display(3);
break;
default:
}
userdata = getUserData();
}
}
int getUserData(){
int choice;
cout << "Enter 1 to view all the neutral items" << endl;
cout << "Enter 2 to view all the helpful items" << endl;
cout << "Enter 3 to view all the harmful items" << endl;
cout << "Enter 4 to exit" << endl;
cin >> choice;
return choice;
}
void display(int x){
ifstream obj;
obj.open("prog2.txt");
string chars;
int powers;
if(x==1){
while(obj>>chars>>powers)
if(powers==0){
cout << chars<<' '<<powers<< endl;
}
}
if(x==2){
while(obj>>chars>>powers)
if(powers>0){
cout << chars<<' '<<powers<< endl;
}
}
if(x==3){
while(obj>>chars>>powers)
if(powers<0){
cout << chars<<' '<<powers<< endl;
}
}
}
This is getting pretty frustrating and any help at all would be highly appreciated!

Your test 'while(userdata =! 4)' is invalid. The 'not is' operator is !=. What the code actually does is while (user data = !4), meaning you're assigning the expression !4 (which is false, hence 0) to userdata. The test condition then evaluates to false and the loop is not entered.

Related

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.

C++ Erase-Remove Idiom not working properly?

This post is a continuation on my post from yesterday: How to output a vector.
So I am in the process of writing a short program that will take a list of strings into a vector, export them to a file, view them before outputting them and lastly remove them if possible. I have managed to get all of the functions working properly except for case 3 (remove a book from the list). The errors I am getting in visual studio as follows:
1.) "No instance of the overloaded function "remove" matches the argument list. [LN 76]
2.) "'Remove': function does not take 2 arguments". [LN 76]
As you can probably tell, I am trying to remove by value instead of index. I am still learning here so be gentle, but why exactly am I getting these errors?
Here is my full code:
#include <iostream>
#include <cctype>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <windows.h>
#include <iomanip>
#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include <istream>
// common namespace
using namespace std;
int main()
{
int option;
bool iWannaLeave = false;
vector<string> bookCollection;
string entryVal = " ";
int anotherOption;
do
{
cout << "Welcome to MyBook! - A text recorder framework application." << endl;
cout << "-----------------------------------------------------------" << endl;
cout << "Main Menu:" << endl;
cout << "1 - Add a book to the collection." << endl;
cout << "2 - Display all books currently in the collection." << endl;
cout << "3 - Remove books from the collection." << endl;
cout << "4 - Write stored collection to file." << endl;
cout << "5 - Quit" << endl;
cout << "Make your selection: ";
cin >> option;
cin.ignore();
switch (option)
{
case 1:
{
bool wannaMoreBooks = false;
// the next loop will execute at least one time so you could enter a book
do
{
wannaMoreBooks = false;
cout << "Add a book title to the collection: ";
getline(cin, entryVal);
bookCollection.push_back(entryVal);
cout << "Would you like to enter another book?(1 - yes, 0 - no): ";
cin >> anotherOption;
cin.ignore();
if (anotherOption == 1) wannaMoreBooks = true;
} while (wannaMoreBooks == true);
}
break;
case 2:
{
for (int i = 0; i < bookCollection.size(); i++)
cout << bookCollection[i] << " | ";
cout << endl;
break;
}
case 3:
{
string vecVal;
cout << "Enter the value you would like to remove: " << endl;
cin >> vecVal;
bookCollection.erase(remove(bookCollection.begin(), vecVal), bookCollection.end());
}
// remove a book from the collection
break;
case 4:
{
ofstream fileOut("Collection.txt");
fileOut << "Your MyBook Collection: [Begin] - | ";
auto first = true;
for (string x : bookCollection)
{
if (!first) { fileOut << " | "; }
first = false;
fileOut << x;
}
fileOut << " | - [End]" << endl;
cout << "Collection.txt has been successfully written." << endl;
break;
}
case 5:
{
//Nested IF to kill program properly
int quitVar;
cout << "Are you sure you want to exit the program?: ";
cin >> quitVar;
cin.ignore();
if (quitVar == 1)
{
cout << "The program will now be terminated." << endl;
iWannaLeave = true;
}
else if (quitVar == 0) cout << "Returning to the main menu." << endl;
}
break;
}
} while (iWannaLeave == false);
return 0;
}
I am aware that this is no where near perfect code so in addition to finding out why I am getting these errors I would also like some constructive criticism as to how I can improve.
Additionally: If I wanted to go about using functions in a header file as opposed to a switch, would I just move the case contents to a header file?
Thanks in advance! :)
Virtually all STL-functions take one or more pairs of iterators. Since you just pass begin, there is no viable overload. You need to call
remove(bookCollection.begin(), bookCollection.end(), vecVal)
It is always a good idea to check the reference, which typically also contains a basic usage example.

C++ - Program returning 0 before finishing my function

EDIT: I've solved the reference issue, thanks for everyone's help, I'm now able to compile and run everything fine, but I can't figure out why the program is returning 0 before finishing the mainMenu() function now:
#include <iostream>
#include <fstream>
using namespace std;
int welcomeScreen(int &success) {
string keyContinue;
bool loop = true;
while(loop) {
cout << "Welcome, traveler! Press 'Q' to continue to the main menu." << endl;
cin >> keyContinue;
if (keyContinue == "q") {
success = 1;
break;
}
}
return success;
}
void mainMenu() {
int success;
int menuSelection;
bool loop;
if (success) {
cout << "MAIN MENU: \n" << endl;
cout << "1. Login \n2. Register" << endl;
while(loop) {
cin >> menuSelection;
switch(menuSelection) {
case 1 : cout << "login screen" << endl;
break;
case 2 : cout << "register screen" << endl;
break;
default : cout << "Please select an option from the menu..." << endl;
}
}
}
}
void exit() {
}
int main()
{
int success;
welcomeScreen(success);
if (success) {
mainMenu();
}
return 0;
}
When I enter 'Q' the program displays 'MAIN MENU' along with the 2 options, but returns 0 before I can choose an option and I can't figure out why. I'm new to learning C++ and this is probably a poor way to go about learning, but I thank everyone for the help.
Try mainMenu (const int &passed) or try to assign success first and pass it afterwards. You are not passing success , but the result of
sucess = 1
Also do you have an prototype for mainMenu ? Try to write
int mainMenu(const int& passed);
before int welcomeScreen ()

In C++, how can I make cin "cancel" if the return key is pressed?

I'm trying to learn C++ by writing a simple console application. The user navigates the main menu by entering a number stored in a variable which a switch statement then uses to determine what to do. It's pretty simple. :)
The issue that's bugging me is that when the program reaches the cin statement, pressing return without entering a number doesn't "exit" the statement but just bumps it down to the next line. I guess this makes sense, but how can I make it so pressing return with no previous input just "exits" or "cancels" the cin statement?
Below is a shortened idea of what my application sort of looks like:
int main()
{
int mainMenuSelector;
while(mainMenuSelector != 4){
cout << "--- MAIN MENU -----------------" << endl;
cout << "[1] First Option" << endl;
cout << "[2] Second Option" << endl;
cout << "[3] Third Option" << endl;
cout << "[4] Exit Application" << endl;
cout << "-------------------------------" << endl;
cout << "Selection: ";
cin >> mainMenuSelector;
// This is the statement I want to move along from
// if the user presses the return key without entering any input.
switch(mainMenuSelector){
case 1:
doSomething();
break;
case 1:
doSomething();
break;
case 2:
doSomething();
break;
case 3:
doSomething();
break;
}
}
return 0;
}
std::string input;
while (std::getline(std::cin, input) && !input.empty()) { /* do stuff here */ }
You might want to go further and verify that the input is valid, doesn't just have a bunch of spaces, etc...
Pressing enter with no input results in an empty string value.
You can do this (try it and adapt it to your code):
#include <string>
#include <iostream>
using namespace std;
int main() {
string s;
getline(cin, s);
while(s != "") { // if the person hits enter, s == "" and leave the loop
cout << s << endl;
getline(cin, s);
}
return 0;
}
If you're specifically looking for options which use the stream operators (rather than parsing the input yourself), you might consider std::stringstream. For example:
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
void ExampleCaptureInput()
{
int value;
string s;
getline(cin, s);
if (s != "")
{
stringstream sstream(s);
sstream >> value;
}
}

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.