Member Avatar for RenFromPenn

Okay, so I have a menu and a linked list, but I have three problems. First of, if you select option one and enter a name it keeps prompting you to enter another and another. It won't accept any other prompt to do anything else like, for instance, exit the program.

Next, I want to be able to insert a name into the list or modify a name. I just can't figure out how to do those two. Any help would be greatly appreciated. The current code that I have generates the following errors:

error C2062: type 'void' unexpected
error C3861: 'modify': identifier not found

If I remove void insertend(void), void modify(void); those errors disappear, but I included them in anticipation of getting the insert and modify features working.

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct names {
  char name[30];
  struct names *next;  /* pointer to next entry */
  struct names *prior;  /* pointer to previous record */
};

struct names *start;  /* pointer to first entry in list */
struct names *last;  /* pointer to last entry */
struct names *find(char *);

void enter(void);
void load(void), list(void);
void insertend(void), void modify(void);
void dls_store(struct names *i, struct names **start,
               struct names **last);
void inputs(char *, char *, int), display(struct names *);
int menu_select(void);

int main(void)
{
  start = last = NULL;  /* initialize start and end pointers */

  for(;;) {
    switch(menu_select()) {
      case 1: enter(); /* enter a name */
        break;
		case 2: insertend(); /* add a name to the list*/
        break;
		case 3: modify(); /* modify a name on the list*/
        break;
		case 5: list(); /* display the list */
        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;

  printf("1. Create a list of names\n");
  printf("2. Insert a name into the list.\n");
  printf("3. Modify a name on list.\n");
  printf("4. Delete a name from list.\n");
  printf("5. Display the list\n");
  printf("6. Load the file\n");
  printf("6. Quit\n");
  do {
    printf("\nEnter your choice: ");
    gets(s);
    c = atoi(s);
  } while(c<0 || c>7);
  return c;
}

/* Enter names. */
void enter(void)
{
  struct names *info;

  for(;;) {
    info = (struct names *)malloc(sizeof(struct names));
    if(!info) {
      printf("\nout of memory");
      return;
    }

    inputs("Enter name: ", info->name, 30);
    if(!info->name[0]) break;  /* stop entering */

    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 {
    printf(prompt);
    fgets(p, 254, stdin);
    if(strlen(p) > count) printf("\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 names *i,   /* new element */
  struct names **start, /* first element in list */
  struct names **last /* last element in list */
)
{
  struct names *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 names **start, struct names **last)
{
  struct names *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 a name. */
struct names *find( char *name)
{
  struct names *info;

  info = start;
  while(info) {
    if(!strcmp(name, info->name)) return info;
    info = info->next;  /* get next name */
  }
  printf("Name not found.\n");
  return NULL;  /* not found */
}

/* Display the entire list. */
void list(void)
{
  struct names *info;

  info = start;
  while(info) {
    display(info);
    info = info->next;  /* get next name*/
  }
  printf("\n\n");
}

/* This function prints the fields. */
void display(struct names *info)
{
    printf("%s\n", info->name);
    printf("\n\n");
}

/* Load the file. */
void load()
{
  struct names *info;
  FILE *fp;

  fp = fopen("mlist", "rb");
  if(!fp) {
    printf("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;

  printf("\nLoading File\n");
  while(!feof(fp)) {
    info = (struct names *) malloc(sizeof(struct names));
    if(!info) {
      printf("Out of Memory");
      return;
    }
    if(1 != fread(info, sizeof(struct names), 1, fp)) break;
    dls_store(info, &start, &last);
  }
  fclose(fp);
}

I'll try and look at it anyway, but if you have an error, why don't you include where the error came from (almost all compilers will give you a line number).

Also, when posting C code, please use C code tags [code=c]/* code here */ [/code] like this:

/* code here */

to get line numbers and syntax highlighting.

Your code has:

void load(void), list(void);
void insertend(void), void modify(void);

It should be: (You're declaring functions, not variables)

void load(void);
void list(void);
void insertend(void);
void modify(void);

Your posted code did not define void insertend(void) or void modify(void) If you're not prepared to implement them now, declare them as stubs:

void insertend(void)
{
}

void modify(void)
{
}

Your menu has two options 6's:

printf("6. Load the file\n");
  printf("6. Quit\n");

maybe one should be 7?

When I ran the program, it stopped taking names when I entered a blank name. It then re-displayed the menu.

Member Avatar for RenFromPenn

Thanks for taking a look at it. I eagerly await your response. Sorry about the code tags. I clicked the button to place them, but I must have accidently pasted over them. Yes, that should be a 7. I accidently entered 6 in there twice.

You had mentioned that it took you back to the menu when you entered a blank name. Well, that's good that you could get back to the menu, but it seems a bit confusing. You would almost have to explain to the user that they must hit enter to get back to the menu and, maybe it's just me, that that just seems to confuse things. To me, it seems like you should just be able to enter a different number after you enter a name instead of being continually prompted for name after name.

If you changed inputs("Enter name: ", info->name, 30); to inputs("Enter name (leave blank to quit): ", info->name, 30); the way to quit would be clear.

(Did you really need my advice for that?)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.