-
Deleting from an array
Greetings all from the land of Utterly Lost and Confused :)
this is my problem!
1. I created this an array of pointers to point to my PIM structure and made it a size 100.
2. I dynamically create each structure with new in my add function.
3. I added menu item that allows the user to select an entry for deletion.
4. When a element is deleted, make sure it is skipped when the print menu item is selected.
My Problem begins here, I enter 4 records, print the records to see all 4 records, I'm suppossed to delete the second record then reprint with the edited data.
It DOES NOT WORK :( I'm not understanding what I'm doing wrong.
I know its a little long but for the love of GOD someone Please help before my head explodes from thinking tooooooo hard.
This is the main of my program
/*************************************************
* This is my main Function for my PIM file. From here I call *
* my menu function. The Purpose of this program is to prompt *
* the user at the menu to either add to the contacts list or *
* display the contacts list or exit the program. I will do *
* this by setting up a loop to call various funtions to *
* perform these operations until the exit option is choosen. *
*************************************************/
#include "pim.hpp"
void main()
{
menu();
}
This is my Header File
#ifndef PIM_HPP
#define PIM_HPP
#include <iostream>
using namespace std;
#define CLS system("cls")
#define MAXRECS 100
const int Namelen = 25;
const int Addrlen = 25;
const int Citylen = 10;
const int Slen = 3;
const int Zlen = 6;
const int Plen = 13;
const int Blen = 5;
/*************************************************
* This is my personal info structure or my contact list if *
* you prefer. This sets how my incoming data is storred in *
* the array. This is also need to get the data out in the *
* correct format and order. *
*************************************************/
struct pinfo
{
char name[Namelen];
char address[Addrlen+1];
char city[Citylen+1];
char state[Slen+1];
char zip[Zlen+1];
char phonenum[Plen+1];
char byear[Blen+1];
};
/*************************************************
* This is where I declare my functions to use in my program. *
* My menu function, add_contact, and print_contact function *
* are defined in the PIM.cpp file. *
*************************************************/
void menu(void);
int add_contact(pinfo *pfile);
void print_contact(pinfo *pfile,int &numrecs);
//void remove_contact(pinfo *pfile);
#endif
This is my PIM.cpp file
/*************************************************
* Welcome to My menu function, this is where I will print the*
* PIM menu to select which function to perform. My loop *
* process is begun here and will continue until the exit *
* option is selected from the menu. I am also using the NEW *
* operator to dynamically create each structure. This menu *
* calls the add_contact and the print_contact functions when *
* selected. The Exit command is also executed from here.
*************************************************/
#include "pim.hpp"
void menu(void)
{
pinfo * pfile[MAXRECS];
int choice, numrecs = 0;
while(1)
{
cout << "Program# 1A 20-Jan-2002 Eddie Williams\n"
<< "------------------------------------------------------------\n"
<< "Welcome to the P.I.M. (Personal Information Manager Program)\n"
<< endl
<< "Please Select From The Following Menu Options."
<< endl
<< endl
<< " 1. ADD New Contact"
<< endl
<< " 2. Print Contact Information"
<< endl
<< " 3. Remove Contact Information"
<< endl
<< " 4. Exit"
<< endl
<< "------------------------------------------------------------\n"
<< endl
<< "Select the operation to perform: ";
cin >> choice;
cin.get();
if ((choice < 1) || (choice > 4))
{
cout << "Error your selection is not valid!"
<< " Press enter to select again.\n";
exit(EXIT_SUCCESS);
}
switch(choice)
{
/*************************************************
* This is the 1 switch statement if the user selects the add *
* option in the menu, the add_contact function is executed. *
* Once the function has completed it breaks out of the switch*
* and reprints the menu to allow the user to select his next *
* option.
*************************************************/
case 1:
CLS;
numrecs = add_contact(pfile);
break;
/*************************************************
* This is the 2nd switch statement if the user selects the *
* Print option in the menu, the print_contact function is *
* executed. Once the function has completed it breaks out of *
* the switch and reprints the menu to allow the user to *
* select his next option.
************************************************/
case 2:
CLS;
print_contact(pfile, numrecs);
break;
/*************************************************
* This is the 3rd switch statement, when the user selects *
* this option the remove contact function is called and *
* prompts the user to select the record number they wish to *
* remove from their contact list, then removes the record *
* they wish to have deleted.
*************************************************/
case 3:
//remove_contact(pfile);
break;
/*************************************************
* This is the 4rd switch statement, when the user selects *
* this option the loop is terminated and the program ends.
*************************************************/
case 4:
delete pfile;
return;
/*************************************************
* This is the default option incase the user input is not *
* within the range of the valid choices.
*************************************************/
default:
CLS;
menu();
}
}
}
/*************************************************
* Hey you made it to my add_contact function :) I will prompt*
* the user to tell me how many records he wishes to add, then*
* I set my loop limit to load my array based on user input *
* for number of records to add, I will output the current *
* record count and the max records allowed in my PIM file. *
* At this point I check to ensure that I do not exceed the *
* array limit. Now I'm ready to start getting my data from *
* the user to load my array. I continue to do this until I *
* reach my record loop limit. *
*************************************************/
int add_contact(pinfo *pfile)
{
CLS;
cout << "How many Records do you wish to add ? ";
int numrecs=0;
cin >> numrecs;
cin.get();
char lname[15]; // temporary variable for my last name
char fname[11]; // temporary variable for my first name
char mname[2]; // temporary variable for my middle initial
for(int i=0;i<numrecs;i++)
{
cout << "Current record count is: " << numrecs << endl;
cout << "Max records allowed is " << MAXRECS << endl
<< endl;
if(i > MAXRECS)
{
cout << "\nSorry your P.I.M. list is Full, No more records can be added.\n";
}
else
{
cout << "Please enter record # " << i+1 << endl;
cout << "Enter Last Name: ";
cin >> lname;
cin.get();
cout << "\nEnter First Name: ";
cin >> fname;
cin.get();
cout << "\nEnter MI: ";
cin >> mname;
cin.get();
string tempname; // Stringing the last name, first name,
tempname.append(lname); // and middle initial into a temporary
tempname.append(", "); // variable called tempname, to string
tempname.append(fname); // copy into our array as one element
tempname.append(" "); // instead of 3 seperate fields.
tempname.append(mname);
tempname.append(".");
strcpy(pfile[i]->name, tempname.c_str());
cout << "\nEnter Street Address: ";
cin.getline(pfile[i]->address, Addrlen);
cout << "\nEnter City: ";
cin.getline(pfile[i]->city, Citylen);
cout << "\nEnter State(example TX): ";
cin.getline(pfile[i]->state, Slen);
cout << "\nEnter Zip(example 12345): ";
cin.getline(pfile[i]->zip, Zlen);
cout << "\nEnter Phone Number(example 123-456-7890): ";
cin.getline(pfile[i]->phonenum, Plen);
cout << "\nEnter Year of Birth(example 1970): ";
cin.getline(pfile[i]->byear, Blen);
CLS;
}
}
return numrecs; // returning numrecs to use in my print_contact function
}
/*************************************************
* Woo Hoo Hey now we get to see if the array loaded correctly*
* From here my output headings are displayed then my loop is *
* initiated to output the array, I use cout.width to set *
* fixed field widths for my Name and my address fields. I *
* catch the return value of numrecs from add_function to set *
* my output loop limit. *
*************************************************/
void print_contact(pinfo *pfile,int &numrecs)
{
CLS;
cout << "Rec#| Name | Address | Phone |Born\n";
cout << "--------------------------------------------------------------------------\n";
for(int i=0;i<numrecs;i++)
{
if (pfile[i] != NULL)
{
cout << " " << i+1 << ": ";
cout.setf(ios::left, ios::adjustfield);
cout.width(26);
cout << pfile[i]->name;
cout.setf(ios::left, ios::adjustfield);
cout.width(26);
cout << pfile[i]->address;
cout << pfile[i]->phonenum << " " << pfile[i]->byear << endl
<< " ";
cout << pfile[i]->city << ", "
<< pfile[i]->state << " " << pfile[i]->zip << endl;
}
}
cout << "\n\n Press Enter to return to the main menu! ";
fflush(stdin);
cin.get();
CLS;
}
/*
void remove_contact(pinfo *pfile)
{
cout << "What Contact record do you wish to remove from the PIM ?" << endl;
int del_rec = 0, i = 0;
cin >> del_rec;
cin.get();
if ((del_rec < 1) || (del_rec > numrecs))
{
cout << "Sorry your selection doesn't match any record in the PIM file!" << endl;
break;
}
else
{
i = (del_rec - 1);
delete pfile[i];
pfile[i] = NULL;
}
}
*/
-
here is an idea
imagine an array of numbers
1 2 3 4 5 6 7
What would be a good way to remove the number three. You could shift everything in the array back... or... you could do this...
1 2 7 4 5 6
Think of how you can do that with your situation.
detete pfile[i]; is not the way you want to go.
>>>
cout << "How many Records do you wish to add ? ";
int numrecs=0;
<<<
Bad practice. Reverse these.
I am not going to go through all of it. Try to make an object of what you are trying to do. Call that object once you get it to work on the smaller scale. When you post code on the board use the code tags. [ code ] and [/ code ] without the spaces.
-
I thank you for the reply, But ....
I understand the logic behind deleting from the array.
The syntax for how this is done is what I don't understand, any one have an example of how I can delete from the array using say an array of pointers.
Array of Pointers to------------------------------------>MyArray
ptr-1---------------------------------------------------> element1
ptr-2---------------------------------------------------> element2
ptr-3---------------------------------------------------> element3
ptr-4---------------------------------------------------> element4
if I wish to delete element 2 from my array how do I do this? As I said I understand the logic, just not the syntax to do it. I have read 3 books so far and no examples have I been able to find. It's hard for me to understand unless I see a example and can walk myself thru it. thanks for any help you can give :)
-
void menu(void);
int add_contact(pinfo **pfile);
void print_contact(pinfo **pfile,int numrecs);
void remove_contact(pinfo **pfile,int numrecs);
.
.
void menu(void)
{
.
.
case 4:
for (int i=0; i<numrecs; i++)
delete pfile[i];
return;
.
.
int add_contact(pinfo **pfile)
{
.
.
//Need to allocate memory here
pfile[i] = new pinfo;
strcpy(pfile[i]->name, tempname.c_str());
.
.
void remove_contact(pinfo **pfile,int numrecs)
If you want to get fancy with your remove_contact() function, you could move everything down when you delete a record. If you do this, then you would need to return a new numrecs.
-
>If you want to get fancy with your remove_contact() function, you could move everything down when you delete a record.
Make that: move everything up.
-
There are two ways (at least) you can do this:
1) add another member variable to the struct to act as a flag, say this:
int active = 1;
If the user wants to "delete" the record, which means you don't print it, then change the value of active to 0. In the print loop, you evaluate each elements active status with this:
if(array[i].active == 1)
//print.
That way you don't have to shift array items at all. This style seems to fit the requirement for #4 better than
2) you can shift array elements to fill in/overwrite the deleted element. If the element you want to delete has index i, then I think it's best to shift all elements one to the left, or down one. That is element with index i + 1 is rewritten to element with index i, element i + 2 is written to element i + 1, element i + 3 is written to element i + 2, etc, but every element less than i remains right where it is (index remains unchanged). Of course you need to know how many elements there are to know when to stop, but you can either keep a variable with the last used index to do that for you and change the variables value whenever you add or delete an element from the array, or you can calculate it using sizeof operator. Then when it comes time to print the values in the array you don't have to evaluate the flag, you just loop through and print whatever is there.