The part of code where I rename the file just won't work. I tried writing it separately in another project, it works. Help me please.
#include <iostream>
#include <stdio.h>
#include <fstream>
using namespace std;
int main () {
char address[] = "";
char newname[] = "";
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
ADDRESS:cin >> address;
fstream file(address);
if (!file.good()) {
cout << "The selected file does not exist! Try again. ";
goto ADDRESS;
} else {
cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
ACTION:cin >> action;
if (action == 1) {
cout << 1;
} else if (action == 2) {
cout << "Enter the new name: ";
cin >> newname;
cout << "Are you sure you want to rename the selected file? Y/N ";
CONFIRM:cin >> confirm;
if (confirm == 'Y' || 'y') {
result = rename(address, newname);
if (result == 0) {
cout << "renamed";
} else {
perror("not renamed");
}
} else if (confirm == 'N' || 'n') {
cout << "No";
} else {
cout << "You typed an invalid command! Try again. ";
goto CONFIRM;
}
} else if (action == 3) {
cout << 3;
} else {
cout << "You typed an invalid command! Try again." << endl;
goto ACTION;
}
}
return 0;
}
BTW the whole code is not finished, so check just the renaming part. Thanks.
Well, this is the solution.
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
using namespace std;
int main() {
string address;
string newname;
Here you can see I used strings instead of char arrays.
char input;
int action;
char confirm;
int result;
cout << "File Manipulator 1.0" << endl;
cout << "--------------------" << endl << endl;
cout << "Type the full address of a file you wish to manipulate." << endl << endl;
getline(cin, address);
ifstream myfile(address.c_str());
I used ifstream with c_str() function which passes contents of a std::string into a C style string.
// try to open the file
if (myfile.is_open())
{
When the condition is met, you must close the opened file in order to be able to manipulate/work with it later.
myfile.close();
CREATE:cout << endl << "-----------------------------------" << endl;
cout << "Type 1 to move the selected file." << endl;
cout << "Type 2 to rename the selected file." << endl;
cout << "Type 3 to delete the selected file." << endl;
cout << "-----------------------------------" << endl << endl;
cin >> action;
switch (action)
{
case 1:
{
// do nothing.
}
break;
case 2:
{
// rename file.
cout << "Enter the new name" << endl << endl;
cin.ignore();
I used here the ignore() function to ignores the amount of characters I specify when I call it.
getline(cin, newname);
cout << "Are you sure you want ot rename the selected file ? Y/N" << endl << endl;
cin >> confirm;
if (confirm == 'Y' || confirm == 'y')
{
Same case with c_str() that i explained earlier.
rename(address.c_str(), newname.c_str());
}
}
break;
case 3:
{
// delete file.
remove(address.c_str());
}
break;
default:
{
cout << "You typed an invalid command!" << endl;
}
break;
}
}
else
{
cout << "The selected file does not exist! Would you like to create it? ";
cin >> input;
If the file name you input doesn't exist, you are prompted to create a file with the specified name, then you are redirected with goto to the manipulation menu.
if (input == 'y' || input == 'Y')
{
// create the file.
ofstream output(address.c_str());
output.close();
cout << "File created";
goto CREATE;
}
}
return 0;
}
Thanks for trying anyway :)
Related
I've been attempting this for awhile but I keep getting lost the more I look into it.
I've been attempting to create a system which allows a user to input their sign up details, have them stored in a file, then later have a login which validates that file.
So far, I've come up with some code, but it's like it's only reading the start of the file and only validating that. I know it shouldn't work, but I don't know how to go about fixing it.
#include <iostream>
#include <string>
#include <fstream>
#include <string.h>
using namespace std;
class file {
private:
string Name, password;
string ID;
public:
void Display();
int Menu();
void addtofile();
void VerifyPass();
};
int main()
{
file Obj;
Obj.Menu();
Obj.Display();
Obj.addtofile();
Obj.VerifyPass();
}
int file::Menu() // The
{
int Option = 0;
attemp:
system("cls");
cout << "1: Sign u " << endl;
cout << "2: Login: " << endl;
cout << "3: Exit" << endl;
cout << "Select Option: " << endl;
cin >> Option;
switch(Option)
{
case 1:
addtofile();
break;
case 2:
VerifyPass();
break;
case 3:
exit(0);
break;
default:
cout << "Wrong Input, attempt again";
goto attemp;
}
return 0;
}
void file::addtofile() // Sign up pag:
{
// system("cls");
ofstream File("Test.txt");
cout << "Sign Up: \n \n \n";
cout << "Enter Name: ";
cin >> Name;
File << Name << endl;
cout << "Enter Password: ";
cin >> password;
File << password << endl;
cout << "Enter ID: ";
cin >> ID;
File << ID << "\n";
File.close();
// cout << "Finished" << endl;
// system("cls"); //
Menu();
}
void file::VerifyPass() // For verifying the user has inputted the correct information
{
string line1;
string PasswordInput2;
string NameInput2;
string IDInput2;
bool IsNamevalid = false;
bool IsIDvalid = false;
bool IsPassvalid = true;
do {
ifstream input("Test.txt", ios::app); // Iosapp is from my understanding, a pointer which allows the program to navigate a file.
system("cls");
cout << "Login: \n";
cout << "Enter Name: " << endl;
cin >> NameInput2;
cout << "Enter Password: " << endl;
cin >> PasswordInput2;
cout << "Enter ID: " << endl;
cin >> IDInput2;
while (!input.eof())
{ // eof is end of file
getline(input, line1);
if (NameInput2 == line1)
{
IsNamevalid = true;
}
if (PasswordInput2 == line1)
{
IsNamevalid = true;
}
if (IDInput2 == line1)
{
IsIDvalid = true;
}
input.close();
}
if (IsNamevalid == false)
{
cout << "Wrong Name , please attempt again" << endl;
input.close();
system("pause");
}
if (IsPassvalid == false)
{
cout << "Wrong Password, Please attempt again" << endl;
input.close();
system("pause");
}
if (IsIDvalid == false)
{
cout << "Invalid ID, please attempt again" << endl;
system("pause");
}
else
{
"Login Successful";
}
} while (IsNamevalid, IsPassvalid, IsIDvalid == false);
system("pause");
}
void file::Display() // just displays what the user inputted for the sign up page
{
system("cls");
string text;
ifstream Readfile("Test.txt");
while (getline(Readfile, text))
{
cout << text << endl;
}
Readfile.close();
cout << "Click to continue to Menu" << endl;
system("pause");
Menu();
}
There are a lot of problems with your code.
main() should not be calling addtofile() and VerifyPass() since those are called inside of Menu().
Menu() should use a do..while loop instead of goto.
VerifyPass() using !eof() in a loop is wrong (Display() loops correctly).
addtofile() is not specifying any flags when opening the file, so it wipes out the existing data. You need to specify the ios::app flag to preserve any existing data. Using ios::app on an ifstream, as you are currently doing in VerifyPass(), is wrong. ios::app is an output-only flag, so it should be used on the ofstream in addtofile() instead.
addtofile() adds 3 new lines to the file per entry, but VerifyPass() only reads in and validates 1 line at a time. You need to read in 3 lines at a time and validate them together as a whole.
With that said, try something more like this instead:
#include <iostream>
#include <string>
#include <fstream>
#include <limits>
#include <cstdlib>
using namespace std;
class file {
public:
void Display();
void Menu();
void AddToFile();
void VerifyPass();
};
int main()
{
file Obj;
do
{
Obj.Menu();
Obj.Display();
}
while (true);
}
void file::Menu()
{
int Option = 0;
system("cls");
do
{
cout << "1: Sign u " << endl;
cout << "2: Login: " << endl;
cout << "3: Exit" << endl;
cout << "Select Option: " << endl;
cin >> Option;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
switch (Option)
{
case 1:
AddToFile();
return;
case 2:
VerifyPass();
return;
case 3:
exit(0);
return;
default:
cout << "Wrong Input, try again" << endl;
break;
}
}
while (true);
}
void file::AddToFile()
{
ofstream File("Test.txt", ios::ate);
if (!File.is_open())
{
cout << "Can't open/create file" << endl;
system("pause");
return;
}
string Name, Password, ID;
cout << "Sign Up: \n \n \n";
cout << "Enter Name: ";
getline(cin, Name);
File << Name << '\n';
cout << "Enter Password: ";
getline(cin, Password);
File << Password << '\n';
cout << "Enter ID: ";
getline(cin, ID);
File << ID << '\n';
File.close();
cout << "Finished" << endl;
system("pause");
}
void file::VerifyPass()
{
string line1, line2, line3;
string PasswordInput;
string NameInput;
string IDInput;
bool IsNamevalid = false;
bool IsIDvalid = false;
bool IsPassvalid = false;
ifstream input("Test.txt");
if (!input.is_open())
{
cout << "Can't open file" << endl;
system("pause");
return;
}
system("cls");
cout << "Login: \n";
cout << "Enter Name: " << endl;
getline(cin, NameInput);
cout << "Enter Password: " << endl;
getline(cin, PasswordInput);
cout << "Enter ID: " << endl;
getline(cin, IDInput);
while (getline(input, line1) &&
getline(input, line2) &&
getline(input, line3))
{
if (NameInput == line1)
{
IsNamevalid = true;
if (PasswordInput == line2)
{
IsPassvalid = true;
if (IDInput == line3)
{
IsIDvalid = true;
break;
}
}
}
}
input.close();
if (!IsNamevalid)
{
cout << "Wrong Name, please try again" << endl;
}
else if (!IsPassvalid)
{
cout << "Wrong Password, please try again" << endl;
}
else if (!IsIDvalid)
{
cout << "Invalid ID, please try again" << endl;
}
else
{
cout << "Login Successful";
}
system("pause");
}
void file::Display()
{
system("cls");
string text;
ifstream Readfile("Test.txt");
while (getline(Readfile, text)) {
cout << text << endl;
}
Readfile.close();
system("pause");
}
I'm working on a program very important to my programming class, and there's something I can't quite figure out; When I try to read from a binary file I've created after opening the program, it fails even if the file's in the directory, and after I try to wipe the contents of the file, I can still 'read' them from the file even though said file is empty when I examine it in explorer. I've determined from this that even though I'm using BinaryFile.read, it's not truly reading from the file, and instead reading from variables stored in the program itself. How can I get my program to read from the actual file?
(please note that this is not yet a complete program, hence the commented sections and empty functions.)
(Also please note that, due to the nature of my class, I am only allowed to use what has been taught already (namely, anything in the fstream header and most things before which are necessary to make a basic program - he's letting me use things in stdio.h, as well.)
//
// main.cpp
// Binary Program
//
// Created by Henry Fowler on 11/19/14.
// Copyright (c) 2014 Bergen Community College. All rights reserved.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdlib>
#include <math.h>
#include <stdio.h>
using namespace std;
struct Record
{
char Name[20];
char LastName[20];
double Pay;
int Clearance;
int ID;
};
void CreateFile(fstream&); //Working
void CheckExist(fstream&); //Working
void Populate(fstream&,Record[],int&,int&); //Working
void Display(fstream&,Record[],int&,int&); //Working
void Append(fstream&,Record[],int&,int&); //Working
void DeleteFromFile(fstream&,fstream&,Record[],int&,int&);
// void SearchInFile(fstream&,Record[],int&,int&);
// void ModifyRecord(fstream&,Record[],int&,int&);
//void SortFile();
void WipeFile(fstream&);
void DelFile(fstream&);
int main(int argc, const char * argv[])
{
Record EmpRecords[20];
char Binary[] = "BinaryFile.dat";
char Binary2[] = "BinaryFileTemp.dat";
int maxsize; //make sure to set i to max size so you can use it later for things like wiping the file or deleting specific records
fstream BinaryFile;
fstream BinaryFile2;
string InputStr;
// char Read;
//int Choice = 0;
int i = 0;
int choice = 0;
int switchchoice;
CreateFile(BinaryFile); //working
CheckExist(BinaryFile); //working
BinaryFile.close();
while(choice==0)
{
cout << "Options: " << endl;
cout << "End Program (0)" << endl;
cout << "Input new records to file (1)" << endl;
cout << "Display current contents of file (2)" << endl;
cout << "Append a record at the end of the file (3)" << endl;
cout << "Delete a record from the file (4)" << endl;
cout << "Search for a record in the file (5)" << endl;
cout << "Modify a certain record (6)" << endl;
cout << "Sort file (unimplemented)" << endl;
cout << "Wipe contents of file (8)" << endl;
cout << "Please choose an option: ";
cin >> switchchoice;
switch(switchchoice)
{
case 0:
{
cout << "Exiting.";
BinaryFile.close();
system("PAUSE");
return 0;
break;
}
case 1:
{
Populate(BinaryFile, EmpRecords,i,maxsize); //working
break;
}
case 2:
{
Display(BinaryFile, EmpRecords,i,maxsize); //working i think
break;
}
case 3:
{
Append(BinaryFile, EmpRecords,i,maxsize); //working
break;
}
case 4:
{
DeleteFromFile(BinaryFile,BinaryFile2,EmpRecords,i,maxsize); //!
break;
}
case 5:
{
// SearchInFile(BinaryFile, EmpRecords,i,maxsize); //!
break;
}
case 6:
{
// ModifyRecord(BinaryFile, EmpRecords,i,maxsize); //!
break;
}
case 7:
{
cout << "Error, file sorting is currently unimplemented. Please try again.";
break;
}
case 8:
{
WipeFile(BinaryFile);
break;
}
}
}
system("PAUSE");
return 0;
}
void CreateFile(fstream& BinaryFile)
{
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary);
}
void CheckExist(fstream &BinaryFile)
{
if(BinaryFile.good())
{
cout << endl << "File does exist" << endl;
}
else
{
cout << "file named can not be found \n";
system("PAUSE");
}
}
void Populate(fstream &BinaryFile,Record EmpRecords[],int &i, int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary);
int choice = 0;
while(choice==0)
{
cout << "Please input employee first name: ";
cin >> EmpRecords[i].Name;
cout << "Please input employee last name: ";
cin >> EmpRecords[i].LastName;
cout << "Please input Employee Pay: ";
cin >> EmpRecords[i].Pay;
cout << "Please input Employee Clearance (1-10): ";
cin >> EmpRecords[i].Clearance;
cout << "Please input Employee ID (6 numbers, i.e. 122934): ";
cin >> EmpRecords[i].ID;
cout << "Input another employee's information? (0) = yes, (1) = no: ";
cin >> choice;
BinaryFile.write((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
i = i+1;
}
maxsize = i;
cout << "i is " << i << endl;
cout << "maxsize is " << maxsize << endl;
BinaryFile.close();
}
void Display(fstream &BinaryFile,Record EmpRecords[],int &i,int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::in | ios::binary | ios::app);
int i2 = maxsize;
i = 0;
while(i2>0)
{
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
cout << i << endl;
cout << EmpRecords[i].Name << " " << EmpRecords[i].LastName << endl;
cout << "Pay: $" << EmpRecords[i].Pay << endl;
cout << "Clearance: " << EmpRecords[i].Clearance << endl;
cout << "Employee ID: " << EmpRecords[i].ID << endl;
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
cout << endl;
i2 = i2-1;
i = i+1;
}
BinaryFile.close();
}
void Append(fstream &BinaryFile,Record EmpRecords[],int &i,int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::out|ios::binary|ios::ate|ios::app);
cout << "Please input employee first name: ";
cin >> EmpRecords[maxsize].Name;
cout << "Please input employee last name: ";
cin >> EmpRecords[maxsize].LastName;
cout << "Please input Employee Pay: ";
cin >> EmpRecords[maxsize].Pay;
cout << "Please input Employee Clearance (1-10): ";
cin >> EmpRecords[maxsize].Clearance;
cout << "Please input Employee ID (6 numbers, i.e. 122934): ";
cin >> EmpRecords[maxsize].ID;
cout << "Input another employee's information? (0) = yes, (1) = no: ";
BinaryFile.write((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
maxsize = maxsize+1;
cout << "maxsize is " << maxsize << endl;
BinaryFile.close();
}
void DeleteFromFile(fstream &BinaryFile,fstream &BinaryFile2, Record EmpRecords[],int &i,int &maxsize)
{
BinaryFile.open("BinaryFile.dat", ios::out|ios::binary|ios::app);
BinaryFile2.open("BinaryFileTemp.dat", ios::out|ios::binary|ios::app);
int Choice;
cout << "Would you like to delete a file by name or by employee number?" << endl;
cout << "Name (1)" << endl;
cout << "Number (2)" << endl;
cout << "Choice: ";
cin >> Choice;
int i2 = maxsize;
if(Choice==1)
{
cout << "Please input employee first name: ";
// cin >> firstname;
cout << "Please input employee last name: ";
// cin >> lastname;
cout << "Searching...";
int i2 = maxsize;
i = 0;
while(i2>0)
{
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
cout << i << endl;
BinaryFile.read((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
// if(EmpRecords[i].Name == firstname)
// {
// cout << "Found first name." << endl;
// if (EmpRecords[i].LastName == lastname)
// {
// cout << "Found last name." << endl;
/// }
// }
// else
// {
// cout << "Could not find name.";
// // BinaryFile2.write((char *) (&EmpRecords[i]),sizeof(EmpRecords[i]));
// }
cout << endl;
i2 = i2-1;
i = i+1;
}
}
BinaryFile.close();
if( remove( "BinaryFile.dat" ) != 0 )
cout << endl << "Error deleting file" << endl;
else
{
cout << "File successfully deleted" << endl << endl;
}
int result;
char oldname[]="BinaryFileTemp.dat";
char newname[]="BinaryFile.dat";
result = rename(oldname,newname);
if(result == 0)
cout << "DEBUG: Success" << endl;
else
cout << "DEBUG: Failure" << endl;
}
void WipeFile(fstream &BinaryFile)
{
int sure;
cout << "There is no undoing this action." << endl;
cout << "Continue (1)" << endl;
cout << "Cancel (2)" << endl;
cout << "Wipe file? ";
cin >> sure;
if(sure == 1)
{
cout << "Wiping file.";
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary | ios::trunc);
BinaryFile.close();
}
else
{
cout << "Canceling.";
}
}
void DelFile(fstream &BinaryFile)
{
BinaryFile.close();
if( remove( "BinaryFile.dat" ) != 0 )
cout << endl << "Error deleting file" << endl;
else
{
cout << "File successfully deleted" << endl << endl;
}
}
Here the problem seems to be, even though you are wiping the file contents, you are not clearing the data you had stored in Record EmpRecords[20]; or the int maxsize value.
Few things you can do inside void WipeFile(fstream &BinaryFile) function: To keep it simple, we'll just reset maxsize to 0:
Pass the maxsize variable as reference to WipeFile(), the same way you are passing for Populate()
Update maxsize = 0, to indicate all the records are removed, when you delete the file contents.
It is better to memset the contents of EmpRecords as well similarly.
For now, I just modified your code to reset maxsize to 0 in WipeFile() and it worked.
void WipeFile(fstream &BinaryFile, int &maxsize)
{
int sure;
cout << "There is no undoing this action." << endl;
cout << "Continue (1)" << endl;
cout << "Cancel (2)" << endl;
cout << "Wipe file? ";
cin >> sure;
if(sure == 1)
{
cout << "Wiping file.";
BinaryFile.open("BinaryFile.dat", ios::out | ios::binary | ios::trunc);
BinaryFile.close();
maxsize = 0;
}
else
{
cout << "Cancelling.";
}
}
There are two main problems with my program that I am currently having. The first is I am unable to add more than one account to my program while it is running (I need to close it and re-open before I can add another). The second issue is when I don't add any accounts to my program addresses get saved to the program, this is what the file looks like when I don't add any accounts to the program.
123#John Smith#0#0###-1.07374e+008#-1.07374e+008#
The first part of the file is correct, but the addresses are coming from somewhere else in memory. This is what my code looks like.
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include <fstream>
#include <sstream>
using namespace std;
struct account
{
string acctNum;
string name;
float cBal;
float sBal;
};
int menu();
char subMenu();
int loadCustomers(account[]);
void saveCusomers(account[], int);
int newCustomer(account[], int);
int deleteCustomer(account[], int);
int findCustomer(account[], int);
void deposit(account[], int);
void withdrawl(account[], int);
void balance(account[], int);
void bankBalance(account[], int);
int main()
{
account acc[20];
int selection;
int numAcc = 0;
int search;
numAcc = loadCustomers(acc);
do
{
selection = menu();
if(selection == 1)
{
newCustomer(acc, numAcc);
}
else if(selection == 2)
{
deleteCustomer(acc, numAcc);
}
else if(selection == 3)
{
search = findCustomer(acc, numAcc);
if (search == -1)
{
cout << "That account doesn't exist." << endl;
system("pause");
system("cls");
}
else
{
cout << right << setw(3) << acc[search].acctNum << "" << left << setw(15) << acc[search].name << acc[search].cBal << acc[search].sBal << endl;
system("pause");
system("cls");
}
}
else if(selection == 4)
{
deposit(acc, numAcc);
}
else if(selection == 5)
{
withdrawl(acc, numAcc);
}
else if(selection == 6)
{
balance(acc, numAcc);
}
else if(selection == 7)
{
bankBalance(acc, numAcc);
}
else if(selection == 8)
{
break;
}
} while (selection != 8);
saveCusomers(acc, numAcc);
return 0;
}
int menu()
{
int select;
cout << "Main Menu" << endl;
cout << "=============" << endl;
cout << "1. New Account" << endl;
cout << "2. Delete Account" << endl;
cout << "3. Find Customer" << endl;
cout << "4. Deposit" << endl;
cout << "5. Withdrawl" << endl;
cout << "6. Balance" << endl;
cout << "7. Bank Balance" << endl;
cout << "8. Exit" << endl;
cout << "=============" << endl;
cout << "Enter choice: ";
cin >> select;
while (select < 1 || select > 8)
{
cout << "Invalid input, select a number between 1 and 8: ";
cin >> select;
}
system("cls");
return select;
}
char subMenu()
{
char choice;
cout << "Which account? <C>hecking or <S>aving: ";
cin >> choice;
while(choice != 'C' && choice != 'c' && choice != 'S' && choice != 's')
{
cout << "Invalid choice, choose either checking or saving: ";
cin >> choice;
}
return choice;
}
int loadCustomers(account acc[])
{
ifstream inFile;
int numCustomers = 0, i = 0;
string ctemp, stemp;
inFile.open("customer.dat");
if (!inFile)
{
cout << "No customer file found." << endl;
}
else
{
cout << "Customer file found..." << endl << endl;
while (getline(inFile, acc[i].acctNum, '#'))
{
getline(inFile, acc[i].name, '#');
getline(inFile, ctemp, '#');
getline(inFile, stemp, '#');
istringstream(ctemp) >> acc[i].cBal;
istringstream(stemp) >> acc[i].sBal;
i++;
numCustomers++;
}
cout << "Number of customers found in file: " << numCustomers << endl;
}
system("pause");
system("cls");
inFile.close();
return numCustomers;
}
void saveCusomers(account acc[], int numCustomers)
{
ofstream outFile;
outFile.open("customer.dat");
for (int i = 0; i < numCustomers; i++)
{
outFile << acc[i].acctNum;
outFile << '#';
outFile << acc[i].name;
outFile << '#';
outFile << acc[i].cBal;
outFile << '#';
outFile << acc[i].sBal;
outFile << '#';
}
outFile << acc[numCustomers].acctNum;
outFile << '#';
outFile << acc[numCustomers].name;
outFile << '#';
outFile << acc[numCustomers].cBal;
outFile << '#';
outFile << acc[numCustomers].sBal;
outFile << '#';
cout << numCustomers + 1 << " accounts saved into the file." << endl;
outFile.close();
}
int newCustomer(account acc[], int numCustomers)
{
cout << "New Customer" << endl;
cout << "============" << endl;
cout << "Enter account number: ";
cin >> acc[numCustomers].acctNum;
cout << "Enter name: ";
cin.ignore();
getline(cin, acc[numCustomers].name);
acc[numCustomers].cBal = 0;
acc[numCustomers].sBal = 0;
numCustomers++;
return numCustomers;
}
int deleteCustomer(account[], int)
{
return 0;
}
int findCustomer(account acc[], int numCustomers)
{
string target;
cout << "Enter the account number you are looking for: ";
cin >> target;
for (int i = 0; i < numCustomers; i++)
{
if (acc[i].acctNum == target)
{
return i;
}
}
return -1;
}
How can I change this to make it so I can add more than one account when the program is running, and how can I make it so the program won't save an address to my file when nothing is added? I would also like to know why those addresses are being saved like that.
In main() you loadCustomers() in acc[] and you keep a record of the number of customers in local variable numAcc. At the end of main() you saveCustomers() the numAcc in acc[].
1. Your saving function is wrong:
in your loop for (int i = 0; i < numCustomers; i++) { ...}, you first write each customer from 0 to numAcc-1. This is correct.
But afterwards you write again an additional account, with the offset of numAcc. So you're writng one more account than you have. And the values of this account are not initialized, which explains the weird numbers you see.
You do this even if no account was added. And you know that you are doing it, because you've written cout << numCustomers + 1 << " accounts saved into the file."
Correction: just save the accounts you have, in the loop.
2.Your adding function is correct but you don't use it as you've planned:
When you add a customer with newCustomer() your function increments its local variable so that it knows that there is one more customer. Your function correctly returns this new number.
Unfortunately, in main() you do nothing with this returned value, so that numAcc remains unchanged.
Correction: Correct the following statement in main():
if (selection == 1)
{
numAcc = newCustomer(acc, numAcc); // update the number of accounts
}
3. Miscellaneous remarks:
You don't check in newCustomers() if your acc[] array is already full. If you add a 21st account, it'll be a segfault !
The same applies to load. You cannot be sure that nobody added a line to the file with a text editor. So there is as well a risk of reading more lines that there is space in your arry.
Nothing happens in deleteCustomer() I suppose you haven't written it yet. Think that this function could change the number of accounts, exactly as newCustomer().
As most banks have more than twenty customers, I assume that it's an exercise for school. I don't know if you're allowed to do so, but I'd highly recommend to replace arrays with vectors.
i need to prevent the junk left in the buffer as entering a value for a switch case menu from being used in a function called by the menu where their is user input.
menu code
void menu()
{
bool done = false;
string input;
while(!done)
{
cout << "Welcome to the DVD database." << endl;
cout << "1. Add A DVD" << endl;
cout << "2. Delete a DVD." << endl;
cout << "3. Edit a DVD." << endl;
cout << "4. List By Category." << endl;
cout << "5. Retrieve by a DVD by Title." << endl;
cout << "6. Display collection by year" << endl;
cout << "7. Display collection by title" << endl;
cout << "-999. Exit program" << endl;
cout << "Please choose an option by entering the corresponding number" << endl;
cin >> input;
int value = atoi(input.c_str());
switch(value)
{
case 1:addDVD(); break;
case 2:deleteDVD(); break;
// case 3:editDVD(); break;
case 4:listByCategory();break;
case 6:displayByYear();break;
case 7:displayByTitle();break;
case -999: writeToFile(); exit(0); break;
default : cout <<"Invalid entry"<< endl; break;
}
}
}
void retrieveByTitle()
{
string search;
int size = database.size();
int index = 0;
bool found = false;
cin.ignore();
cout << "Please enter the title of the DVD you would like to retrieve: " << endl;
getline(cin,search);
cout << search;
while(!found && index<size)
{
if(database.at(index)->getTitle().compare(search)==0)
{
cout << database.at(index)->toString();
break;
}
}
cout << endl;
}
if 5 is entered in the menu, the program skips the user input in the method
This code works, but it has the same problem you describe if you eliminate the 'cin.ignore()', which removes the extra delimiters ignored by the cin >> operator:
#include <iostream>
#include <climits>
using namespace std;
int main() {
string a, b;
while (true) {
cout << "write 'x' to exit: " << endl;
cin >> a;
if (a == "x") {
break;
}
cout << "read '" << a << "'" << endl;
cout << "now write a line: " << endl;
cin.clear(); // clears cin status
cin.ignore(INT_MAX); // clears existing, unprocessed input
getline(cin, a);
cout << "read '" << a << "'" << endl;
}
return 0;
}
When dealing with interactive user input you should use std::getline()
The std::cin is flushed to the application every time you hit <enter>. So this is the logical junks you should read data from the user in.
std::string answer;
std::cout << "Question:\n";
std::getline(std::cin, answer);
This gets you everything the user provided in response to the previous question.
Once you have the input you should get the value you think is on the input. Once you have this you should check if there is any other junk on the input (if there is then abort and re-try) otherwise validate the data you expected.
If you were expected an integer;
std::stringstream linestream(answer);
int value;
std::string junk;
if ((answer >> value)) && (!(answer >> junk)))
{
// If you got data
// and there was no junk on the line you are now good to go
}
In your specific example there is already a simple way to do this:
std::getline(std::cin, input);
int value = boost::lexical_cast<int>(input); // throws an exception if there is not
// an int on the input (with no junk)
I was looking at some code I'm working on, and there are 3-4 errors that I have tried for about a week to get rid of, and I just can't do it! I'm kind of new to programming, so if you could answer in stupid form, that would be great! Here is the code.
#include <iostream>
#include <string>
using namespace std;
int main() {
string password;
int choice;
cout << "Command Line Multi-Tool" << endl;
cout << endl;
cout << "plase enter your password: " << endl;
cin >> password;
if (password == "creeper1") {
cout << endl;
cout << "Main Menu" << endl;
cout << "1. Class Schedule" << endl;
cout << "2. School Info" << endl;
cout << "3. Exit" << endl;
cin >> choice;
}
else {
cout << "Incorrect, Access Denied" << endl;
return(0);
}
}
else (password == "admin1"){
cout << "/*adminLogin=='1'*/" << endl;
cout << endl;
cout << "Menu::Main" << endl;
}
return(0);
}
}
And here is the error log.
/Users/student/Documents/TO BE FILED/Tuesday/main.cpp:31:0 /Users/student/Documents/TO BE
FILED/Tuesday/main.cpp:31: error: expected unqualified-id before 'else'
/Users/student/Documents/TO BE FILED/Tuesday/main.cpp:36:0 /Users/student/Documents/TO BE
FILED/Tuesday/main.cpp:36: error: expected unqualified-id before 'return'
/Users/student/Documents/TO BE FILED/Tuesday/main.cpp:36:0 /Users/student/Documents/TO BE
FILED/Tuesday/main.cpp:36: error: expected declaration before '}' token
Again thanks so much!
You have one if but 2 else brances in your code. Decide which one you want and lose the other one. Looking at the code you probably want
if (password == "creeper1") {
cout << endl;
cout << "Main Menu" << endl;
cout << "1. Class Schedule" << endl;
cout << "2. School Info" << endl;
cout << "3. Exit" << endl;
cin >> choice;
} else if (password == "admin1")
// Your processing code here
} else {
cout << "Incorrect, Access Denied" << endl;
return(0);
}
Unbalanced else,i.e. without a corresponding if.
Perhaps you wanted something like:
if (password == "creeper1") {
}
else if (password == "admin1") {
}
else {
}
You can't use an else if after an else, that block will never be executed.Also, the right syntax is return 0, not return(0).
You also include extra braces, but if you indent the code in the right way you see when a block ends and starts, so you could rarely make mistakes like adding an extra brace:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string password;
int choice;
cout << "Command Line Multi-Tool" << endl;
cout << endl;
cout << "plase enter your password: " << endl;
cin >> password;
if (password == "creeper1")
{
cout << endl;
cout << "Main Menu" << endl;
cout << "1. Class Schedule" << endl;
cout << "2. School Info" << endl;
cout << "3. Exit" << endl;
cin >> choice;
}
else if(password == "admin1")
{
cout << "/*adminLogin=='1'*/" << endl;
cout << endl;
cout << "Menu::Main" << endl;
}
else
{
cout << "Incorrect, Access Denied" << endl;
return 0;
}
return 0;
}
This is the code with all the syntax errors fixed.About semantics I don't know if it works, but now you can compile and execute it, to test the code.
becasue else cannot comprise judgement
the correct usage is like this:
if(password == "creeper1"){
}
else if(password == "admin1"){
}
else{
}