C++ Phone Book - User Input Into Arrays - c++

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.

Related

Delete data from a dynamically allocated array in c++

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!

Is there a way to use strcpy to copy a string array into another string or different array?

It's me again!
I am still way to new at C++, and just turned in an assignment yesterday creating a menu with 7 options to pick from. I was able to complete all the tasks required except for option 7, which was to copy an array to another array and cout the new array.
I know my code does not show it in case 7, but is there anyone who can let me know how I would complete the task with the current code I have? It will not help me with the assignment anymore, but I feel it is something that I should be able to do. Maybe I spent too long in front of the screen and searching for answers that it just eluded me.... in any circumstance, I would appreciate any help I can get for my future programs.
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main(void)
{
// Delcarations
string MasterFile[6]; // MasterFile Array
MasterFile[0] = "I want to thank all the C++ students who has helped me this semester. You have inspired me to work harder and to be able to design small C++ programs using a gamming approach.";
string master = MasterFile[0];
string str1 = "my Instructor, Professor Penn";
string str2 = "I want to thank all the C++ students who has helped me this semester. You have inspired me to work harder and to be able to design efficient C++ programs using a gamming approach.";
char masterfile[] = { "I want to thank all the C++ students who has helped me this semester. You have inspired me to work harder and to be able to design small C++ programs using a gamming approach." };
char StudentFile[1] = {masterfile[1]}; // StudentFile Array
char selection;
// Defines the width of the menu
const int menuWidth = 84;
// This is a loop structure for the menu box using ASCII
// This prints the top left corner of the menu box (ASCII)
cout << char(201);
// This prints the top border of the menu box (ASCII)
for (int column = 0; column < menuWidth; ++column) {
cout << char(205);
}
// This prints the top right corner of the menu box (ASCII)
cout << char(187);
cout << "\n";
// array with menu options
string menu[20];
menu[0] = " **************";
menu[1] = " *** MAIN MENU ***";
menu[2] = " **************";
menu[3] = " Please Choose From The Following Options:";
menu[6] = " 1. Master File Array Statement:";
menu[8] = " 2. Length of Master File Array:";
menu[10] = " 3. Replacing Phrase 'all the C++ students' with 'my Instructor, Professor Penn':";
menu[12] = " 4. Swaping 'small' with 'efficient':";
menu[14] = " 5. Find and Display the Position of 'th': ";
menu[16] = " 6. Erase the Phrase 'using a gaming approach':";
menu[18] = " 7. Copy MasterFile Array to Student Array:";
for (string option : menu)
{
cout << char(186) // print left border
<< setw(menuWidth) // set next item width
<< left // set next item aligment
<< option // print menu option string with width and aligment
<< char(186) << "\n"; // print right border
}
// This will print the bottom left corner of the menu box (ASCII)
cout << char(200);
// This prints the bottom border of the menu box (ASCII)
for (int column = 0; column < menuWidth; ++column) {
cout << char(205);
}
// This prints the bottom right corner of the menu box (ASCII)
cout << char(188);
cout << "\n\n";
/*
END OF MENU
*/
cout << "\t\t\t Enter Your Selection: ", cin >> selection, cout << endl;
do
{
switch (selection)
{
case '1':
cout << "You have chosen to create Masterfile Array:\n\n";
cout << master; cout << endl;
cout << "\n\n";
break;
case '2':
cout << "You have chosen to display the length:\n\n";
cout << "The number of characters in MasterFile Array is: ";
cout << master.length(), cout << endl;
cout << "\n\n";
break;
case '3':
cout << "You have chosen to replace 'all the C++ students' with 'my Intructor, Professor Penn':\n\n";
cout << master.replace(16, 20, str1), cout << endl;
cout << "\n\n";
break;
case '4':
master.swap(str2);
cout << "You have to swap the word 'small' with 'efficient':\n\n";
cout << master; cout << "\n\n";
break;
case '5':
cout << "You have chosen to find and display the 'th' position:\n\n";
cout << "'th' starts in position: ";
cout << master.find("th"); cout << " of the array."; cout << endl;
cout << "\n\n";
break;
case '6':
cout << "You have chosen to erase the phrase 'using a gaming approach:\n\n";
cout << master.erase(149) << ".", cout << "\n\n";
break;
case '7':
cout << "\nYou have chosen to copy StudentFile Array into MasterFile Array:\n\n";
cout << master;
default: cout << "\n Invalid selection\n\n";
}
} while ((selection = main()) != 7);
return 0;
}
Method 1: The simplest way
As explained in the first answer to this StackOverflow question, if you are using C++11, you can copy one array to another array using std::array. You don't have to worry about using strcpy at all.
std::array<int,4> A = {1,2};
std::array<int,4> B = A; // This copies array A into array B.
So for your specific code, you can simply create a new string array and set it equal to master.
Here is the relevant documentation for std::array.
Method 2: Using strcpy
Alternatively, if you do want to use strcpy, use strcpy_s instead, as strcpy is now considered an unsafe and obsolete function. You can call it like this:
strcpy_s(FirstThing, SecondThing);
which will copy the contents of SecondThing into FirstThing.

On finding vowels and capitals char in the beginning of a string?

I've been making a little memory game as an exercise from a textbook I'm doing. It's called Grandma's trunk and it works by in one turn you found an item in the trunk and the next turn you say you found the previous item and the newest item on this turn...I think.
Mostly it's an exercise on using functions, which I think I've gotten down pretty well. But my output is completely wrong. I've believe I've located the problem in one function where I'm supposed to analyze the first character and decided if it needs an AN or A or THE before the string. There might be a problem with the random function I'm using to throw in predefined items from a small database. The int main() function is supposed to be relatively complete, this is just an exercise to master functions...which I, sorta? Would rather call it novice experience.
I thought that perhaps I was running into the getline bug where it couts a blank line, and from my understanding, is fixed by cin.ignore(); but all that did was force me to press enter twice when I enter data. Which...I sort of like. Perhaps I'm using gizmos like isupper and .at() wrong? I tried using find_first_of but it didn't really change anything.
output calling the storage trunk and the owner grandma and just using word1 word2 word3... wordn....as items found leaves me with the output.
In grandma trunk you've found a
and an ord3 word1.
it completely muddles up the output. I'm starting to think that the int main() body I was given wasn't exactly stellar. But I can't be 100% confident in my article function. Any help would just be incredible. I've been struggling using this among many books and advice from a buddy to teach myself a little about programming. It's been a rather huge headache.
program itself
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
using namespace std;
string CorrectArticle(string phrase);
string GetPhrase(void);
bool Continue(void);
string UpperCase(string);
string RandomItem(void);
const string PUNCTUATION = ".";
int main(){
//Variables
int turn;
bool flag;
string phrase,
article,
story, item,
storage, owner;
srand(time(NULL));
cout << "Welcome to Grandmother's Trunk 9000" << endl;
cout << "This is a memory game. Each turn a player" << endl;
cout << "Says an item to place inside a trunk. " << endl;
cout << "And the next player has to say what the " << endl;
cout << "previous player said plus his/her own item." << endl;
cout << "This will go around in revolving turns." << endl;
cout << endl << endl;
cout << "But Grandma's Trunk is a little dry..." << endl;
cout << "Let's change what the storage is and " << endl;
cout << "Who owns it." << endl << endl;
//define storage variable
cout << "What exactly is this storage?" << endl;
getline (cin, storage);
cout << "So the items are stored in " << storage << endl;
cout << endl;
//define owner
cout << "Who owns this " << storage << " ?" << endl;
getline (cin, owner);
cout << "The owner is " << owner << endl;
story = "In "+ owner + " " + storage + " you've found ";
turn = 0;
flag = Continue();
//While flag is true
while (flag) {
if (turn %2 == 0) {
item = GetPhrase();
} else {
item = RandomItem();
}
//set corrected item to article
article = CorrectArticle(item);
//advance the story every item
story = story + "\n and " + article + " " + item;
cout << story << PUNCTUATION << endl;
turn++;
flag = Continue();
}
return (0);
}
//Gives A, AN, and THE to correct words
// An if phrase starts with i,e,i,o,u or y
// A if phrase starts with other lower case letters
// The for phrases that start with an uppercase letter
string CorrectArticle(string phrase){
int i=0;
string correctedString;
string stringAn;
string stringA;
string stringThe;
stringAn= " an ";
stringA = " a ";
stringThe= "The ";
if (GetPhrase().at(i) = "a" or "e" or "i" or "u"){
correctedString = stringAn + GetPhrase();
}else if (isupper(GetPhrase().at(i))){
correctedString = stringThe + GetPhrase();
}else{
correctedString = stringA + GetPhrase();
}
return correctedString;
}
//This function takes no parameters
//and returns the user's input
string GetPhrase(void){
string itemInput;
cout << "\nWhat did you find? \n" << endl;
getline (cin, itemInput);
cout << "\nYou found " << itemInput << endl;
cin.ignore();
return itemInput;
}
//Asks user if they wish to continue
bool Continue(void){
//return false if no, true if yes
string continueString;
cout << "Would you like to continue?";
cout << " Yes or No would suffice" << endl;
getline(cin,continueString);
UpperCase(continueString);
cout << "You picked " << continueString;
if (UpperCase(continueString).find("NO") != string::npos){
return false;
} else if (UpperCase(continueString).find("YES") != string::npos){
return true;
}
}
//Changes the string to uppercase
string UpperCase(string stringUpper){
int i = 0;
while (i<stringUpper.size()){
stringUpper[i] = toupper(stringUpper[i]);
i++;
}
return stringUpper;
}
//Randomizes items found in game
string RandomItem(void){
int randomNumber;
int maxNumberOfItems = 5;
string randomizedItem;
randomNumber= rand() % maxNumberOfItems;
switch (randomNumber){
case 0:
randomizedItem = "Smaug";
break;
case 1:
randomizedItem = "Batman";
break;
case 2:
randomizedItem = "Yoda";
break;
case 3:
randomizedItem = "Paul Atreides";
break;
case 4:
randomizedItem = "Captain Kirk";
break;
default:
cout << "ERRORRRR! PANIC!" << endl;
}
return randomizedItem;
}
Remember that = is assignment, == for compare.
Also remember that you have to compare variable with value, such as:
if ((string == "a") or (string == "e") ...
If the or works for you, all the best. I've only been able to use ||. Must be compiler conformity issues.
Try this:
bool is_vowel(char letter)
{
const std::string vowels("aeiouAEIOU");
return (vowels.find_first(letter) != std::string::npos);
}
In other words, I place all the vowels in a string a search the string. If there is a match, the letter is a vowel.

How do I use cin in a while loop?

I'm trying to get the user to input their name(s) using a while loop with an array and cin, but after the last person's name is input, the program crashes instead of moving on. Is there a way to fix this, or do I need to completely change up the code? I'm also fairly new to c++, so can any answers be given as simply as possible?
#include <iostream>
#include <string>
using namespace std;
int main()
{
unsigned int numberofplayers;
number://loop back here if more than 4 players
cout << "Number of players: ";
cin >> numberofplayers;
if(numberofplayers > 4 || numberofplayers < 1){
cout << "Invalid number, please enter a number from 1 to 4." << endl;
goto number;
}
string name[numberofplayers];
cout << "Enter your name" << endl;
int a = 1;
while(a < numberofplayers + 1){
cout << "Player " << a << ": ";
cin >> name[a];
cout << "Hello, " << name[a] << "." << endl;
a++;
}
}
You would probably facing array index out of bound, so Change you while loop to this and set a=0 to fill from 0th index.
while(a < numberofplayers){
}
Your last iteration exceeds the size of the array. You need to change it to
while(a < numberofplayers)
also, on another note, the keyword goto isn't used much anymore. I would suggest using a while there also like
while(true){
cout<<"number of players";
cin>>numberofplayers
if(numberofplayers is valid input){
break;
}
cout<<"bad input";
}
There is a question on stackoverflow discussing the use of goto extensively here:
GOTO still considered harmful?

Having problems printing each element of an array of objects [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am working on a project and am stuck with what I think is a scope and a logic problem. I am creating a class called 'Person' with four string variables, last name, first name, favorite color, and gender. I am creating a second class called 'PersonList' with one variable that is an array of 'Person' objects. I have set a const int called MAX that determines the size of the array (currently 3). Ultimately, I would like to enter a the string variables of a 'Person' object into the 'newDude' object declared in the main. For instance, when the 'readNewPerson' function runs, I enter Doe, John, Blue, Male. THIS STEP WORKS!!
Next, I would like this 'newDude' to be copied into the 'dudesList' object declared in the main at address dudesList[0] and the 'readNewPerson' function to run again. If everything works correctly, I am thinking that Smith, Jane, Pink, Female should get copied to dudesList[1] and Johnson, Mike, Green, Male should get copied to dudesList[2]. Finally, I would like to print all three objects to the console.
I am going wrong somewhere in the 'for' loops within the 'addPersonToList' and 'printList' functions where my variable is not iterating properly. My guess is that since I am declaring the counter 'i' inside the function, it dies and resets to zero every time a 'newDude' is created. If I'm correct about this, where is the best place to declare the counter and when should I iterate it?
I really appreciate any feedback anyone might be able to offer and I certainly do not want anyone to DO the assignment for me. I could just use a bit of a push in the right direction at this point as I am incredibly frustrated with what should be a very simple task, at least in concept.
Here is my program so far:
// contact list with one-word strings only
#include <iostream>
using namespace std;
const int MAX = 3;
class Person
{
private:
string dudesLName;
string dudesFName;
string dudesColor;
string dudesGender;
public:
void readNewPerson (); // function declaration to ask for info
void printPerson (); //function declaration to display info to console
};
class PersonList
{
private:
Person dudesList [MAX];
public:
void addPersonToList (Person newDude); //function declaration to add my newDude to the dudesList array
void printList (); //function declaration to print the entire array
};
//the main function is a simple switch-case asking for user choices
int main (void)
{
Person newDude; //one object contains 4 simple string variables
PersonList List; //one object contains an array of [MAX] dudes
int userChoice; //integer for the user's choice in switch-case
cout << "~~Welcome to Stephen's Contact List~~" << endl;
cout << "Please enter your choice:" << endl;
cout << " 1 - enter " << MAX << " new people" << endl;
cout << " 2 - print the contact list" << endl;
cout << " 3 - retrieve by last name" << endl;
cout << " 4 - retrieve by address" << endl;
cout << " 5 - retrieve by gender" << endl;
cin >> userChoice;
switch (userChoice)
{
case 1:
for (int i = 0; i < MAX; i++)
{
newDude.readNewPerson (); //function call to enter one person's info
List.addPersonToList (newDude); //function call to add newDude to dudesList array
}
break;
case 2:
cout << "2 doesn't work yet" << endl;
List.printList (); //function call to print entire list
break;
case 3:
cout << "3 doesn't work yet" << endl;
break;
case 4:
cout << "4 doesn't work yet" << endl;
break;
case 5:
cout << "5 doesn't work yet" << endl;
break;
}
cout << "thanks dude!!" << endl;
return 0;
}
// function definitions
void Person::readNewPerson ()
{
cout << "enter a dude's last name please" << endl;
cin >> dudesLName;
cout << "enter a dude's first name please" << endl;
cin >> dudesFName;
cout << "enter a dude's favorite color please" << endl;
cout << "for test purposes, just enter one word" << endl;
cin >> dudesColor;
cout << "enter a dude's gender please" << endl;
cout << "male or female is fine, so is dude or dudette" << endl;
cin >> dudesGender;
return;
}
void Person::printPerson ()
{
cout << "dude's name is " << dudesLName << ", " << dudesFName << endl;
cout << "his (her?) favorite color is: " << endl;
cout << dudesColor << endl;
cout << "and his (her?) gender is: " << endl;
cout << dudesGender << endl << endl;
return;
}
void PersonList::addPersonToList (Person newDude)
{
for (int i = 0; i < MAX; i++) //supposed to iterate the array address as it adds Person objects to the array
dudesList [i] = newDude; //this is where the newDude object is copied to the array
return;
}
void PersonList::printList()
{
for (int i = 0; i < MAX; i++)
dudesList [i].printPerson ();
return;
}
Okay, what seems to be going wrong, is that you're adding the same person to the list 3 times. when you call addPersonToList
void PersonList::addPersonToList (Person newDude)
{
for (int i = 0; i < MAX; i++) //supposed to iterate the array address as it adds Person objects to the array
dudesList [i] = newDude; //this is where the newDude object is copied to the array
return;
}
now you have a couple of options.
What is probably the easiest to do and to concieve, is to pass the index into your method from where you call it, and make your method like this:
void PersonList::addPersonToList (Person newDude, int index)
{
dudesList [index] = newDude; //this is where the newDude object is copied to the array
}
and then in your switch statement, call it like this
case 1:
for (int i = 0; i < MAX; i++)
{
newDude.readNewPerson (); //function call to enter one person's info
List.addPersonToList (newDude, i); //function call to add newDude to dudesList array
}
Now what is probably the "right" way, is to keep track of what the last index you added was in your PersonList class
class PersonList
{
private:
Person dudesList [MAX];
int indexToAdd = 0; // your new index
public:
void addPersonToList (Person newDude); //function declaration to add my newDude to the dudesList array
void printList (); //function declaration to print the entire array
};
and then incriment that in your addPersonToList method
void PersonList::addPersonToList (Person newDude)
{
for (int i = 0; i < MAX; i++) //supposed to iterate the array address as it adds Person objects to the array
dudesList [indexToAdd] = newDude; //this is where the newDude object is copied to the array
indexToAdd++;
return;
}