I am trying to delete a record from an entered position, from a dynamically allocated array in c++, and when i try to run the program it throws an error stating
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
The insertion and displaying of the records are running perfectly fine, the only thing that throws an error is delete operation.
The Code
#include <iostream>
using namespace std;
struct employee{
string name;
int empId;
string dept;
int age;
};
employee *emp = new employee[5];
void insertData(){
for (int i = 0; i<5; i++){
cout<<"Enter the Employee name"<<endl;
cin>>emp -> name;
cout<<"Enter the Employee Id"<<endl;
cin>>emp -> empId;
cout<<"Enter the Employee Department"<<endl;
cin>>emp -> dept;
cout<<"Enter the Employee age"<<endl;
cin>>emp -> age;
}
}
void displayData(){
for (int i = 0; i < 5; ++i) {
cout<<"Employee"<<i+1<<" Data"<<endl;
cout<<"Name : "<<emp -> name<<endl;
cout<<" Employe ID : "<<emp -> empId<<endl;
cout<<"Department : "<<emp -> dept<<endl;
cout<<"Age : "<<emp -> age<<endl<<endl;
}
}
void deleteData(){
int pos;
cout<<"Enter the position you want to delete Data";
cin>>pos;
if (pos>5){
cout<<"Invalid Size please enter a size smaller than 5";
}
for (int i = pos; i < 5; ++i) {
emp[i] = emp[i+1];
}
}
int menu(){
int x;
do {
int n;
cout << "Please enter the number corresponding to an operation you want to perform\n";
cout << "1. Insert Data" << endl;
cout << "2. Display Data" << endl;
cout << "3. Delete Data" << endl;
cout << "4. Exit" << endl;
cin >> n;
switch (n) {
case 1: {
insertData();
break;
}
case 2: {
displayData();
break;
}
case 3: {
deleteData();
break;
}
case 4: {
exit(0);
}
default:
cout << "Invalid Choice, Enter a valid choice";
return 1;
}
cout<<"Press 1 to continue or 0 to exit";
cin>>x;
} while (x == 1);
}
int main() {
menu();
return 0;
}
Your code has several logic issues.
Inserting and displaying data
When you insert and display data with insertData and displayData you loop over five indices (i) but you never used that variable in your loop. You simply operate all five times on the pointer to the first element in the array.
Deleting data
You print an error message if pos is greater than 5, but then you go ahead and run the rest of the function anyway. A return would break out of the function at this point. Also, I suggest writing to std::cerr for error messages.
You iterate from pos to 4, but copy from index 5, which is out of bounds. This yields undefined behavior. You should change your bounds to i < 4. Because arrays are indexed starting at 0 you also need to start at pos - 1.
You never clear out the data in the last element. As you're only deleting one record at a time, you now it'll always be the last one that needs to be cleared.
void deleteData(){
int pos;
cout<<"Enter the position you want to delete Data";
cin>>pos;
if (pos>5){
cout<<"Invalid Size please enter a size smaller than 5";
}
for (int i = pos; i < 5; ++i) {
emp[i] = emp[i+1];
}
}
Suggested:
void deleteData() {
int pos;
cout << "Enter the position you want to delete Data ";
cin >> pos;
if (pos > 5){
cout << "Invalid Size please enter a size smaller than 5\n";
return;
}
for (int i = pos - 1; i < 4; ++i) {
emp[i] = emp[i+1];
}
emp[4].name = "";
emp[4].empId = 0;
emp[4].dept = "";
emp[4].age = 0;
}
Menu
In your menu function you should initialize x to 1, as you don't error check user input at the end.
You return in the default case, which will prevent the loop from repeating to get a valid input.
You never use the return value of menu and it may not ever return, which your compiler should warn you about. The return type should be void.
void menu() {
int x = 1;
do {
int n;
cout << "Please enter the number corresponding to an operation you want to perform\n";
cout << "1. Insert Data" << endl;
cout << "2. Display Data" << endl;
cout << "3. Delete Data" << endl;
cout << "4. Exit" << endl;
cin >> n;
switch (n) {
case 1:
insertData();
break;
case 2:
displayData();
break;
case 3:
deleteData();
break;
case 4:
exit(0);
default:
cerr << "Invalid Choice, Enter a valid choice";
}
cout << "Press 1 to continue or 0 to exit";
cin >> x;
} while (x == 1);
}
Best practices
You use the magic number 5 a lot. Give it a name so it's easier to modify if needed.
const int NUM_EMPLOYEES = 5;
There are many suggestions. Your array does not have to live at a global scope. It should not. It should be declared inside main and then passed to the functions as an argument.
Further, there is no need for it to be dynamically allocated at all. If you are going to dynamically allocate with new you'll want to remember to de-allocate with delete []. Most modern desktops OSes will automatically release that memory when your program finishes, but it's a good habit to get into.
Alternatively, you can dynamically allocate with a smart pointer and the smart pointer will handle the de-allocation for you.
auto emp = std::make_unique<emp[]>(NUM_EMPLOYEES);
Incorporating some of these ideas might look like:
int main() {
employee emp[NUM_EMPLOYEES];
insertData(emp, NUM_EMPLOYEES);
return 0;
}
You tie modifying your data very closely to the UI. These can and probably should be separated. For instance, you might have a int menu() function that prompts for a menu choice and returns it, but doesn't actually do anything to the data.
int menu() {
while (true) {
cout << "Please enter the number corresponding to an operation you want to perform\n";
cout << "1. Insert Data" << endl;
cout << "2. Display Data" << endl;
cout << "3. Delete Data" << endl;
cout << "4. Exit" << endl;
int choice = 0;
cin >> choice;
if (choice < 1 || choice > 4) {
cerr << "Invalid option." << endl;
continue;
}
return choice;
}
}
You can now use this valid menu choice to decide what to do to your data.
Because all of your functions need to accept this data, you should make your collection of employees a class/struct, and implement these functions as member functions. I suspect that's a bit beyond where you're at with C++, but object oriented programming and model-view-controller design are things to read up on.
This (out of scope) memory allocation is so wrong...
employee *emp = new employee[5];
just do it:
employee emp[5];
In your deleteData() perhaps you want to set entries to zero instead of copying from the next position (I guess this is what delete denotes). For example you may want this implementation:
void deleteData(){
int pos;
cout<<"Enter the position you want to delete Data";
cin>>pos;
if (pos<5) {
emp[pos].name = "";
emp[pos].empId = 0;
emp[pos].dept = "";
emp[pos].age = 0;
} else {
cout<<"Invalid Size please enter a size smaller than 5";
}
}
This implementation prevents the potential out-of-bound errors!
Related
I'm very new at C++ and I am having trouble with my phone book program.
The issue is when I go to add a contact, it saves the name and number in the arrays. If I choose switch case 2 after adding each contact, it'll list all the contacts and phone numbers normally. But if I select switch case 1 multiple times in a row and add more than one contact before I select switch case 2 to display all the contacts, it will only print the most recent contact I added.
The code is unfinished, but I can't seem to figure this one out! When I add more than one contact at a time, does it override the most recent one I just added? Sorry if I am not explaining this well, I'm not yet familiar with all the proper terminology!
I also don't want to use a loop for the input, so the user will not have to input ten names and numbers all at once if they don't want to. Unless there's a way to use a loop and have them end it after a certain amount of entries.
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <string>
using namespace std;
string nameArray[10];
string numberArray[10];
int arraySize = 10;
int index;
int i;
void addContact() {
// Get user input
cout << "\n\tEnter contact information" << endl;
cout << "\t==========================" << endl;
cout << "\tEnter name: ";
getline(cin, nameArray[i]);
cout << "\tEnter phone number: ";
cin >> numberArray[i];
cin.ignore();
}
void viewAll() {
// Declare variables
int pass = -1;
string tempNumber = "";
string tempName = "";
// Sort array in ascending order
for(pass=0; pass<9; pass++) {
for(index = 0; index < (9 - pass); index++) {
if(nameArray[index] > nameArray[index + 1]) {
tempName = nameArray[index];
nameArray[index] = nameArray[index + 1];
nameArray[index + 1] = tempName;
tempNumber = numberArray[index];
numberArray[index] = numberArray[index + 1];
numberArray[index + 1] = tempNumber;
}
}
}
// Print contacts after sort
cout << endl;
for(int j=0; j<arraySize; j++) {
cout << '\t' << nameArray[j] << '\t' << '\t' << numberArray[j] << endl;
}
}
void searchContact() {
}
void editContact() {
}
void deleteContact() {
}
int main() {
int choice;
while(1) {
cout << "\n\t\tMAIN MENU" << endl;
cout << "\t=======================" << endl;
cout << "\t [1] Add Contact" << endl;
cout << "\t [2] View All Contacts" << endl;
cout << "\t [3] Search Contact" << endl;
cout << "\t [4] Edit Contact" << endl;
cout << "\t [5] Delete Contact" << endl;
cout << "\t [6] Exit Program" << endl;
cout << "\t=======================" << endl;
cout << '\t';
cin >> choice;
switch(choice) {
case 1: // Add a new contact
cin.ignore();
addContact();
break;
case 2: // Print all contacts in alphabetical order
viewAll();
break;
case 3: // Search and print contact name and phone number
searchContact();
break;
case 4: // Edit a contact
editContact();
break;
case 5: // Delete a contact
deleteContact();
break;
case 6: // End program
return 0;
break;
default:
cout << "\nInvalid choice." << endl;
break;
}
}
return 0;
}
i think Johnny Mopp has given you the correct answer, but you said your new so i'd like to give you a slightly longer explanation, and a little bonus advice.
Consider your addContact function. You ask for values to be inserted into the name and numbers array at position i. You need to update that position after you add a contact or it will simply overwrite what was there previously. So a ++i; at the end of the function will solve your problem as this means next time you add a contact it goes to the next slot in the array. Now be mindful of this as your array only has (right now) 10 items in it, so once you add 10 entries i will have a value of 10 now which if you try to do nameArray[i] it would be trying to access, or worse write to, the 11th item in your array which does not exist, this is very bad (take a quick google tour of "buffer overflow error"). So make sure you add a safety check in at the start of addContact that checks if i == 10 in which case you could for example: print an error message then return from the function immediately. Definately DO NOT try to access an element of the array that does not exist.
I would also recommend explicitly initialising i to 0 just for clarity (it will be 0 because it is a global variable, but it would not be 0 if it was declared inside a function, so its a good habit to get into)
Finally, you seem to be using a mix of declaring a loop variable outside of the loop for(pass=0;...) and declaring it inside the loop for(int y = 0;...) from what i can see you dont use the variables declared outside of the loop like pass or index for anything except looping, so consider declaring them in the loop where they are used, this just keeps things a bit tidier and avoids mistakes where because the variable is still in scope someone might think its valid to use it as an array index or the likes.
Hope thats useful.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm working on a project, to create a linked list in class but I can't even start working on it because every time I run the program it's will stop working when I want to input data.
Can someone tell me how to input data properly using class? and if possible please let me know how to improve this program. The code that I've done is quite long.
I'll try to make it short and simple for you guys to understand. A lot of people been suggesting me to use std::string but our lecturer never mentioned about it so we have no idea how to use it.
If I have to use it that means I have to start learn it from the beginning which means it will take time for me to really understand it.
We're also required to have a function where we can update the data stored, search the data based on one of its data and make a summary for it.
#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include <conio.h>
#include <stdio.h>
#include <string>
using namespace std;
//CLASS USED IN PROGRAM
class carInsurance
{
private:
int total;
int customerNo;
string name;
string iCno;
char dob[10];
string nationality;
string address;
char phoneNo[15];
string email;
string occupation;
char carNo[10];
char expireDate[11];
float insuranceAmount;
char carUsage[30];
char manufacturingDate[11];
int package;
int option;
int additional;
int noCustomer[10];
public:
void add();
void presetdata();
static void deleteFunc(carInsurance noCustomer[]);
static void viewAll(carInsurance noCustomer[]);
//constructor name has to be the same as class
carInsurance(int carInsurance_total,
int carInsurance_customerNo,
string carInsurance_name,
string carInsurance_iCno,
char carInsurance_dob[10],
string carInsurance_nationality,
string carInsurance_address,
char carInsurance_phoneNo[15],
string carInsurance_email,
string carInsurance_occupation,
char carInsurance_carNo[10],
char carInsurance_expireDate[11],
float carInsurance_insuranceAmount,
char carInsurance_carUsage[30],
char carInsurance_manufacturingDate[11],
int carInsurance_package,
int carInsurance_option,
int carInsurance_additional)
{
total = carInsurance_total;
customerNo = carInsurance_customerNo;
name = carInsurance_name;
iCno = carInsurance_iCno;
dob[10] = carInsurance_dob[10];
nationality = carInsurance_nationality;
address = carInsurance_address;
phoneNo[15] = carInsurance_phoneNo[15];
email = carInsurance_email;
occupation = carInsurance_occupation;
carNo[10] = carInsurance_carNo[10];
expireDate[11] = carInsurance_expireDate[11];
insuranceAmount = carInsurance_insuranceAmount;
carUsage[30] = carInsurance_carUsage[30];
manufacturingDate[11] = carInsurance_manufacturingDate[11];
package = carInsurance_package;
option = carInsurance_option;
additional = carInsurance_additional;
} // end of constructor
carInsurance()
{ // Set all variables to null
total = 0;
customerNo = 0;
name = " ";
iCno = " ";
dob[10] = '\0';
nationality = " ";
address = " ";
phoneNo[15] = '\0';
email = " ";
occupation = " ";
carNo[10] = '\0';
expireDate[11] = '\0';
insuranceAmount = 0;
carUsage[30] = '\0';
manufacturingDate[11] = '\0';
package = 0;
option = 0;
additional = 0;
}
// SET
void setChar(char carInsurance_dob[10],
char carInsurance_phoneNo[15],
char carInsurance_carNo[10],
char carInsurance_expireDate[10],
char carInsurance_carUsage[30],
char carInsurance_manufacturingDate[10])
{dob[10] = carInsurance_dob[10];
phoneNo[15] = carInsurance_phoneNo[15];
carNo[10] = carInsurance_carNo[10];
expireDate[11] = carInsurance_expireDate[11];
carUsage[30] = carInsurance_carUsage[30];
manufacturingDate[11] = carInsurance_manufacturingDate[11];}
void setname(string carInsurance_name){name = carInsurance_name;}
void setiCno(string carInsurance_iCno){iCno = carInsurance_iCno;}
void setAddress(string carInsurance_address){address = carInsurance_address;}
void setString(string carInsurance_nationality, string carInsurance_email,string carInsurance_occupation)
{nationality = carInsurance_nationality; email = carInsurance_email; occupation = carInsurance_occupation;}
void setInt(int carInsurance_total, int carInsurance_customerNo, int carInsurance_package, int carInsurance_option, int carInsurance_additional)
{customerNo = carInsurance_customerNo; package = carInsurance_package; option = carInsurance_option; additional = carInsurance_additional;}
void setFloat (float carInsurance_insuranceAmount){insuranceAmount = carInsurance_insuranceAmount;}
// GET
string getname(){return name;}
string getiCno(){return iCno;}
string getaddress(){return address;}
string getString(){return nationality; return email; return occupation;}
int getInt(){return total; return customerNo; return package; return option; return additional;}
float getFloat(){return insuranceAmount;}
}; //end class
Here goes my main:
//function declaration
//to prevent overload run function outside
void add();
//THE MAIN FUNCTION OF PROGRAM
int main()
{
carInsurance obj; // obj is class object
carInsurance *noCustomer[10];
int choice;
while(choice != 4)
{
cout << "1. ADD, UPDATE, DELETE\n" << "2. SEARCH\n" << "3. VIEW ALL\n" << "4. SUMMARY REPORT\n" << "5. EXIT\n" << endl;
cout << "Enter your choice: ";
cin >> choice;
system("cls");
switch(choice)
{
case 1:
{
cout << "___________________________________\n";
cout << "\n\tADD/UPDATE/DELETE\n";
cout << "___________________________________\n";
cout << "\n1. ADD\n2. UPDATE\n3. DELETE\n" << endl;
cin >> choice;
system("cls");
switch(choice)
{
case 1:
{
int i;
int total = 0;
cout << "How many customer? ";
cin >> total;
for(i=0; i<total; ++i)
{
cout << "________________________________\n";
cout << "\n\tCUSTOMER NO. " << 1 + i;
cout << "\n________________________________\n";
noCustomer[i]->add(); // this is function call to input
}
break;
}
case 2:
{
int paymentID;
//cout << "UPDATE" << endl;
cout << "\nEnter the customer ID that you want to update:";
cin >> paymentID;
// function here
break;
}
case 3:
{
int paymentID;
//cout << "DELETE" << endl;
cout << "\nEnter the customer ID that you want to delete:";
cin >> paymentID;
noCustomer[10]->deleteFunc(noCustomer[10]);
break;
}
} // End of switch case for add,update,delete
system("cls");
break;
} // End of case 1
case 2:
{
cout << "___________________________\n";
cout << "\n\t SEARCH\n";
cout << "___________________________\n";
system("pause");
system("cls");
break;
}
case 3:
{ cout << "___________________________\n";
cout << "\n\tVIEW ALL\n";
cout << "___________________________\n";
obj.presetdata();
noCustomer[10]->viewAll(noCustomer[10]);
cout<<"\n";
system("pause");
system("cls");
break;
}
case 4:
{
cout << "___________________________\n";
cout << "\n\tSUMMARY REPORT\n";
cout << "___________________________\n\n";
cout << "1. Sorted by different month\n2. Sorted by different car type\n3. Sorted by different insurance" << endl;
cin >> choice;
switch(choice)
{
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
default:
cout << "Wrong input! Please choose again: ";
cin >> choice;
system("pause");
}
break;
}
case 5:{
cout << "___________________________\n";
cout << "\n\tTHANK YOU!\t\n";
cout << "___________________________";
exit(0); }
default:
continue;
}// End of switch case
}// End of while
return 0; //indicates success
}//End of main
I see a problem in the inner switch statement:
case 1:
{
int i;
int total = 0;
cout << "How many customer? ";
cin >> total;
for(i=0; i<total; ++i)
{
cout << "________________________________\n";
cout << "\n\tCUSTOMER NO. " << 1 + i;
cout << "\n________________________________\n";
noCustomer[i]->add(); // this is function call to input
break;
}
}
case 2:
The break operator breaks the loop, but does not prevent executing case 2: branch.
Yet another problem: re-assignment of choice. User may input 4 in any input request that will break while (choice != 4) unexpectedly. You can avoid troubles with break and re-assignments by using functions.
There is a lot of out of array bounds access by indexes that are equal to array sizes.
It is not clear what you want to reach in dob[10] = carInsurance_dob[10]; It copies 11th char. Maybe you want to copy the whole char array. Use std::string for error-free code.
I am having an issue when trying to use a getline command where a user can enter in a movie and then add to the collection of movies (stored in "movies.txt")
My code is compiling, but it starts out with the 3rd case automatically. When I press "q" to quit that case, it reverts to the menu, yet when I try and write out the file or print the collection, no movie titles have been saved. Where I should go from here? I feel like I'm on the cusp of understanding this.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int ARRAY_SIZE = 200;
string movieTitle [ARRAY_SIZE];
int loadData (string pathname);
int writeData (string pathname);
int getTitle (string movieTitle[]);
void showAll (int count);
int main()
{
loadData("movies.txt");
char userInput;
string movieTitle[ARRAY_SIZE];
int count = getTitle(movieTitle);
bool endOfProgram = false;
while (endOfProgram ==false)
{
cout << "1. Read in Collection" << endl;
cout << "2. Print Collection" << endl;
cout << "3. Add a Movie to the Collection" << endl;
cout << "4. Write out Collection" << endl;
cout << "5. Quit the Program" <<endl;
cin >> userInput;
switch(userInput)
{
case('1'):
{
loadData("movies.txt");
break;
}
case('2'):
{
showAll(loadData("movies.txt"));
break;
}
case('3'):
{
cout << getTitle(movieTitle);
break;
}
case('4'):
{
cout <<"Write out Collection" << endl;
writeData("movies.txt");
break;
case('5'):
{
endOfProgram=true;
cout << "Have a nice day" <<endl;
break;
}
}
}
}
}
int loadData (string pathname)
{
int count = 0;
ifstream inFile;
inFile.open(pathname.c_str());
if (!inFile)
return -1;
else
{
while(!inFile.eof())
{
getline(inFile, movieTitle[count]);
count++;
}
}
return count;
}
int writeData (string pathname)
{
ofstream outfile;
outfile.open("movies.txt");
if(!outfile.is_open())
{
cout << "Cannot open movies.txt" << endl;
return -1;
}
outfile.close();
return 0;
}
void showAll (int count)
{
cout << "\n";
for (int i=0; i< count; i++)
{
cout << movieTitle[i] << endl;
}
cout << "\n";
}
int getTitle (string movieTitle[])
{
string movie;
int count = 0;
while(true)
{
cout <<"Enter Movie Titles (Type 'q' to quit)" <<endl;
cin >> movie;
if (movie == "q")
{
break;
}
movieTitle [count] = movie;
count++;
}
return count;
}
I believe cin reads until eol is found, i.e. the user presses return.
So look for integer in the userInput variable, and pass that to your switch statement
int nr = atoi(userInput.c_str())
switch(nr){
case 1:
case 2: etc ...
In your codes it is not clear why it directly goes to case '3'. It should wait for a user input first. Seems like something already available in buffer. Just put one cout statement in case '3': and check what it print. If possible put break point there and run the application in debug mode and check the value. Hope this will help you.
case('3'):
{
cout<<"Value of userInput is: "<<userInput<<endl;
cout << getTitle(movieTitle);
break;
}
Alternately you can add the below line of code just before cin like below
std::cin.clear();
cin >> userInput;
I recommend inputting an integer instead of a character for your input.
You will need to change the case values too:
int selection = 0;
//...
cin >> selection;
switch (selection)
{
case 1:
//...
}
You won't have to worry about characters in the buffer. The stream will fail if an integer is not read.
I need to ask the user to input 8 zip codes and then store them in an array of integers and then to output them one by one , each being in a new line.These two things should be done in separate functions. But when it runs the code first time it shows only menu, then second time in loop when i enter L and input 8 zipcodes it shows this error
Enter your choice: libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string(in here optionInChar=optionInString.at(0);)
using namespace std;
void DisplayCityZipCodes();
int LoadCityZipCodes(int ZipCodes[],int SIZE);
void DisplayCityZipCodes(int ZipCodes[],int SIZE);
void DisplayMenu();
char GetOption();
int main(){
int const SIZE=8;
int ZipCodes[SIZE]={0};
bool moreWork=true;
option=GetOption();
while(moreWork) {
DisplayMenu();
option=GetOption();
switch(option){
case 'L':
ZipCodes[SIZE]= LoadCityZipCodes(ZipCodes, SIZE);
break;
cout<<"D";
case 'D': DisplayCityZipCodes(ZipCodes, SIZE);
break;
}
}
}
void DisplayMenu(){
cout<<" **********************\n\n";
cout<<" San Jose City Zip codes\n\n";
cout<<" **********************\n\n";
cout<<"1. Load City zip codes\n";
cout<<"2. Display all City zip codes\n";
cout<<"3. Search a City zip code\n";
cout<<"4. Reverse the City zip code List\n";
cout<<"5. Quit\n";
}
char GetOption(){
string optionInString="";
char optionInChar='a';
cout<<"\n\nEnter your choice: ";
getline(cin,optionInString);
optionInChar=optionInString.at(0);
cout<<"\n";
return optionInChar;
}
int LoadCityZipCodes(int ZipCodes[],int SIZE){
cout<<"PLease enter 8 city Zip Codes ";
int i=0;
for(;i<8;i=i+1){
cin >>ZipCodes[i];
}
return ZipCodes[i];
}
void DisplayCityZipCodes(int ZipCodes[],int SIZE){
int i=0;
for(;i<8;i=i+1){
cout<<ZipCodes[i]<<endl;
}
}
Now I have not had a hand on C++ for a long time, but this will work.
You should look on the variable declarations and some other things though.
#include<iostream>
#include<conio.h>
using namespace std;
void DisplayCityZipCodes();
void LoadCityZipCodes();
void DisplayMenu();
int const SIZE = 8;
int ZipCodes[SIZE];
int main()
{
DisplayMenu();
return 0;
}
void DisplayMenu()
{
int ch;
cout << " **********************\n\n";
cout << " San Jose City Zip codes\n\n";
cout << " **********************\n\n";
do
{
cout << "1. Load City zip codes\n";
cout << "2. Display all City zip codes\n";
cout << "3. Search a City zip code\n";
cout << "4. Reverse the City zip code List\n";
cout << "5. Quit\n";
cout << "\nPlease enter your choice:";
cin >> ch;
switch (ch)
{
case 1:
LoadCityZipCodes();
break;
case 2:
DisplayCityZipCodes();
break;
case 5:
exit(0); //You will need to include math.h for this.
default:
cout << "please enter a proper choice!";
break;
}
} while (1);
}
void LoadCityZipCodes()
{
cout << "PLease enter 8 city Zip Codes ";
for (int i=0; i<8; i++)
{
cin >> ZipCodes[i];
}
}
void DisplayCityZipCodes()
{
for (int i=0; i<8; i++)
{
cout << ZipCodes[i] << endl;
}
}
You can add remaining of your functions with case 3 and 4.
Try to debug the code and see how it work before you post :)
You need to look closer at the statements
return ZipCodes[i];
and
ZipCodes[SIZE]= LoadCityZipCodes(ZipCodes, SIZE);
In both cases you use ZipCodes[8] which is definitely out of range.
To solve both problems, don't return anything from LoadCityZipCodes (i.e. make it return void), because it already sets the values in the array.
You need to remeber that when programming we start counting at 0. That means for an array that has the size 8 all the valid indexes are: 0, 1, 2, 3, 4, 5, 6, 7. When you try to access your array with ZipCodes[8] you are asking for the 9th element which is out of range.
I am trying to find a way, within my code to search for an object that is in the Vectors that I have used. I am already pushing back the information into the different vectors and I know about .size to display the info. I want the user to be able to enter the bank account number then if that is correct display the contents of the other vectors.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
//declaring four vectors
std::vector<string>names;
std::vector<string>address;
std::vector<int>age;
std::vector<double>accountnumber;
//forward declaration of functions
void namesInput ();
void addressInput ();
void ageInput ();
void accountnumberInput ();
int main()
{
//variable for switch statement
int choice;
system("title HSBC Online Banking");
system("color B6");
cout << "Please select from the following options" << endl;
cout << "----------------------------------------" << endl;
cout << "1. Enter profile " << endl;
cout << "2. Search for client " << endl;
cout << "3. Exit" << endl;
cin >> choice;
switch(choice)
{
case 1:
//calling functions for first switch case
namesInput ();
addressInput ();
ageInput ();
accountnumberInput ();
system("cls");
break;
case 2:
break;
case 3:
system("exit");
break;
}
return 0;
}
void namesInput ()
{
system("cls");
for (int i = 1; i <= 3; i++)
{
string temp;//variable to give to vector
cout<<"Enter " << i << " first, middle and last names : ";
cin>>temp;
names.push_back(temp);//push back into vector
}
}
void addressInput ()
{
system ("cls");
for (int i = 1; i <= 3; i++)
{
string temp;//variable to give to vector
cout<<"Enter " << i << " House Number, Street, Postcode : ";
cin>>temp;
address.push_back(temp);//push back into vector
}
}
void ageInput ()
{
system ("cls");
for (int i = 1; i <= 3; i++)
{
int temp;//variable to give to vector
cout<<"Enter " << i << " Day, Month, Year : ";
cin>>temp;
age.push_back(temp);//push back into vector
}
}
void accountnumberInput ()
{
system ("cls");
for (int i = 1; i <= 1; i++)
{
int temp;//variable to give to vector
cout<<"Enter " << i << " Account Number ";
cin>>temp;
accountnumber.push_back(temp);//push back into vector
}
main ();
}
void findClient ()
{
cout << "To find a client please enter their account number" << endl;
}
std::vector<double>accountnumber;
Using a double for account numbers does not seem a good choice to me: you may want to use a std::string instead.
For example: note that "exact" comparison between doubles is not possible (so searching for account numbers using doubles as keys is problematic); instead you can do that with strings.
So, assuming you use a vector<string> for account numbers, you can use std::find() to find a given account position in the vector, e.g.:
auto it = find(accountNumbers.begin(), accountNumbers.end(),
accountNumberToFind);
if (it != accountNumbers.end())
{
... Found, process it ...
}
Once you have the iterator to the found account, you can get the vector 0-based index from it using a simple pointer/iterator arithmetic like (it - accountNumbers.begin()).
Then, given this index, you can access the corresponding items in the other vectors.
However, from an object-oriented design perspective, I'd prefer defining a class for accounts, with several fields like account number, name, address, etc., and have a single vector<Account> (instead of several vectors of single account attributes).
There are some parts of your code that I'd suggest to revisit, however, according to you code, you can just do the following:
void lookForAccount(){
system ("cls");
for (int i = 1; i <= 1; i++)
{
int temp;//variable to give to vector
cout<<"Enter " << i << " Account Number you want to look for";
cin>>temp;
for(int j = 0;j<accountnumber.size();j++){
if(accountnumber[j]==temp){
cout<<"account number: "<<accountnumber[j]<<", name: "<<names[j]<<"etc..."<<endl;
}
}
}
main ();
}
Instead of this dummy method I'd anyway suggest to use iterators and std::find.
However, as pointed out in comments, this code is bug prone due to several reasons: handling account number by double is not the best choiche. Furthermore, I'd suggest to redesign your code to handle all the account information using a C++ objects.