I am trying to work with a doubly linked list. The best example that I could understand was from a C book. I attempted to convert that example to a functional C++ program.
My limited knowlege of linked lists may have let me astray. But here goes. My program compiles but I do not get the menu.
When I press enter then the menu comes up, but It is not responding to my input. I think my error is with thet gets and the fgets. I read that C++ accepts the gets and fgets syntax with stdio.h header. I am not sure what I need to do to make it work in C++.
Any help is appreciated. I think I applied the code tags correctly in my program. If not, I appoligize. I sincerely tired to make the program code easier to read.
The output is suppose to look like.
1. Enter a name
2. Delete a name
3. List the file
4. Search
5. Save the file
6. Load the file
7. Quit
Enter your choice: 1
Enter name: Jim Black
Enter street: 258 Nowh
Enter city: Duno
Enter state: CA
Enter zip: 258913
Enter name:
1. Enter a name
2. Delete a name
3. List the file
4. Search
5. Save the file
6. Load the file
7. Quit
Enter your choice:
// My listed list program
#include <stdio.h> //
#include <stdlib.h> // For atoi function
#include <string.h> // for strcmp function
#include <iostream.h>
struct address
{
char name[30];
char street[40];
char city[20];
char state[3];
char zip[11];
struct address *next; // pointer to next entry
struct address *prior; // pointer to previous record
};
struct address *start; // pointer to first entry in list
struct address *last; // pointer to last entry
struct address *find(char *);
void enter(void), search(void), save(void);
void load(void), list(void);
void mldelete(struct address **, struct address **);
void dls_store(struct address *i, struct address **start,
struct address **last);
void inputs(char *, char *, int), display(struct address *);
int menu_select(void);
int main(void)
{
start = last = NULL; // initialize start and end pointers
for(;;) // Forever
{
switch(menu_select())
{
case 1: enter(); // enter an address
break;
case 2: mldelete(&start, &last); // remove an address
break;
case 3: list(); // display the list
break;
case 4: search(); // find an address
break;
case 5: save(); // save list to disk
break;
case 6: load(); // read from disk
break;
case 7: exit(0);
}
}
return 0;
}
// Select an operation.
int menu_select(void)
{
char s[80];
int c;
cout <<endl;
cout << "1. Enter a name\n";
cout << "2. Delete a name\n";
cout << "3. List the file\n";
cout << "4. Search\n";
cout << "5. Save the file\n";
cout << "6. Load the file\n";
cout << "7. Quit\n";
do
{
cout << "\nEnter your choice: ";
gets(s);
c = atoi(s);
} while(c<0 || c>7);
return c;
}
// Enter names and addresses.
void enter(void)
{
struct address *info;
for(;;) {
info = (struct address *)malloc(sizeof(struct address));
if(!info) {
cout <<"\nout of memory";
return;
}
inputs ("Enter name: ", info->name, 30);
if(!info->name[0]) break; // stop entering
inputs ("Enter street: ", info->street, 40);
inputs ("Enter city: ", info->city, 20);
inputs ("Enter state: ", info->state, 3);
inputs ("Enter zip: ", info->zip, 10);
dls_store(info, &start, &last);
} // entry loop
}
// This function will input a string up to
// the length in count and will prevent
// the string from being overrun. It will also
// display a prompting message.
void inputs(char *prompt, char *s, int count)
{
char p[255];
do
{
cout << prompt;
fgets(p, 254, stdin); // look at this //
if(strlen(p) > count) cout << "\nToo Long\n";
}
while(strlen(p) > count);
p[strlen(p)-1] = 0; // remove newline character
strcpy(s, p);
}
// Create a doubly linked list in sorted order.
void dls_store
(
struct address *i, // new element
struct address **start, // first element in list
struct address **last // last element in list
)
{
struct address *old, *p;
if(*last==NULL)
{ // first element in list
i->next = NULL;
i->prior = NULL;
*last = i;
*start = i;
return;
}
p = *start; // start at top of list
old = NULL;
while(p)
{
if(strcmp(p->name, i->name)<0)
{
old = p;
p = p->next;
}
else
{
if(p->prior)
{
p->prior->next = i;
i->next = p;
i->prior = p->prior;
p->prior = i;
return;
}
i->next = p; // new first element
i->prior = NULL;
p->prior = i;
*start = i;
return;
}
}
old->next = i; // put on end
i->next = NULL;
i->prior = old;
*last = i;
}
// Remove an element from the list.
void mldelete(struct address **start, struct address **last)
{
struct address *info;
char s[80];
inputs("Enter name: ", s, 30);
info = find(s);
if(info)
{
if(*start==info)
{
*start=info->next;
if(*start) (*start)->prior = NULL;
else *last = NULL;
}
else
{
info->prior->next = info->next;
if(info!=*last)
info->next->prior = info->prior;
else
*last = info->prior;
}
free(info); // return memory to system
}
}
// Find an address.
struct address *find( char *name)
{
struct address *info;
info = start;
while(info)
{
if(!strcmp(name, info->name)) return info;
info = info->next; // get next address
}
cout << "Name not found.\n";
return NULL; // not found
}
// Display the entire list.
void list(void)
{
struct address *info;
info = start;
while(info)
{
display(info);
info = info->next; // get next address
}
cout << "\n\n";
}
// This function actually prints the fields in each address.
void display(struct address *info)
{
cout << info->name;
cout << info->street;
cout << info->city;
cout << info->state;
cout << info->zip;
cout << endl << endl;
}
// Look for a name in the list.
void search(void)
{
char name[40];
struct address *info;
cout << "Enter name to find: ";
gets(name);
info = find(name);
if(!info)
cout << "Not Found" << endl;
else display(info);
}
// Save the file to disk.
void save(void)
{
struct address *info;
FILE *fp;
fp = fopen("mlist", "wb");
if(!fp)
{
cout << "Cannot open file.\n";
exit(1);
}
cout << "\nSaving File\n";
info = start;
while(info)
{
fwrite(info, sizeof(struct address), 1, fp);
info = info->next; // get next address
}
fclose(fp);
}
// Load the address file.
void load()
{
struct address *info;
FILE *fp;
{
fp = fopen("mlist", "rb"); // open binary file for update // reading & writing.
if(!fp)
{
cout << "Cannot open file.\n";
exit(1);
}
// free any previously allocated memory
while(start)
{
info = start->next;
free(info);
start = info;
}
// reset top and bottom pointers
start = last = NULL;
cout <<"\nLoading File\n";
while(!feof(fp))
{
info = (struct address *) malloc(sizeof(struct address));
if(!info)
{
cout << "Out of Memory";
return;
}
if(1 != fread(info, sizeof(struct address), 1, fp)) break;
dls_store(info, &start, &last);
}
fclose(fp);
}