C/Structure/Structure Array

Материал из C\C++ эксперт
Перейти к: навигация, поиск

A simple mailing list example using an array of structures

/*
C: The Complete Reference, 4th Ed. (Paperback)
by Herbert Schildt
ISBN: 0072121246
Publisher: McGraw-Hill Osborne Media; 4 edition (April 26, 2000)
*/
/* A simple mailing list example using an array of structures. */
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct addr {
  char name[30];
  char street[40];
  char city[20];
  char state[3];
  unsigned long int zip;
} addr_list[MAX];
void init_list(void), enter(void);
void delete(void), list(void);
int menu_select(void), find_free(void);
int main(void)
{
  char choice;
  init_list(); /* initialize the structure array */
  for(;;) {
    choice = menu_select();
    switch(choice) {
      case 1: enter();
        break;
      case 2: delete();
        break;
      case 3: list();
        break;
      case 4: exit(0);
    }
  }
  return 0;
}
/* Initialize the list. */
void init_list(void)
{
  register int t;
  for(t=0; t<MAX; ++t) addr_list[t].name[0] = "\0";
}
/* Get a menu selection. */
int menu_select(void)
{
  char s[80];
  int c;
  printf("1. Enter a name\n");
  printf("2. Delete a name\n");
  printf("3. List the file\n");
  printf("4. Quit\n");
  do {
    printf("\nEnter your choice: ");
    gets(s);
    c = atoi(s);
  } while(c<0 || c>4);
  return c;
}
/* Input addresses into the list. */
void enter(void)
{
  int slot;
  char s[80];
  slot = find_free();
  if(slot==-1) {
    printf("\nList Full");
    return;
  }
  printf("Enter name: ");
  gets(addr_list[slot].name);
  printf("Enter street: ");
  gets(addr_list[slot].street);
  printf("Enter city: ");
  gets(addr_list[slot].city);
  printf("Enter state: ");
  gets(addr_list[slot].state);
  printf("Enter zip: ");
  gets(s);
  addr_list[slot].zip = strtoul(s, "\0", 10);
}
/* Find an unused structure. */
int find_free(void)
{
  register int t;
  for(t=0; addr_list[t].name[0] && t<MAX; ++t) ;
  if(t==MAX) return -1; /* no slots free */
  return t;
}
/* Delete an address. */
void delete(void)
{
  register int slot;
  char s[80];
  printf("enter record #: ");
  gets(s);
  slot = atoi(s);
  if(slot>=0 && slot < MAX)
    addr_list[slot].name[0] = "\0";
}
/* Display the list on the screen. */
void list(void)
{
  register int t;
  for(t=0; t<MAX; ++t) {
    if(addr_list[t].name[0]) {
      printf("%s\n", addr_list[t].name);
      printf("%s\n", addr_list[t].street);
      printf("%s\n", addr_list[t].city);
      printf("%s\n", addr_list[t].state);
      printf("%lu\n\n", addr_list[t].zip);
    }
  }
  printf("\n\n");
}


Daisy chaining the horses both ways

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct cat
{
     int age;
     int height;
     char name[20];
     char father[20];
     char mother[20];
     struct cat *next;     /* Pointer to next structure         */
     struct cat *previous; /* Pointer to previous structure     */
};
int main()
{
   struct cat *first = NULL;
   struct cat *current = NULL;
   struct cat *last = NULL;
   char test = "\0";
   for( ; ; ) {
     printf("\nDo you want to enter details of a%s cat (Y or N)? ", first == NULL?"nother " : "");
     scanf(" %c", &test );
     if(tolower(test) == "n")
       break;
     /* Allocate memory for each new cat structure */
     current = (struct cat*)malloc(sizeof(struct cat));
     if( first == NULL )
     {
       first = current;            /* Set pointer to first cat   */
       current->previous = NULL;
     }
     else
     {
       last->next = current;    /* Set next address for previous cat */
       current->previous = last; /* Previous address for current cat */
     }
     printf("\nEnter the name of the cat: ");
     scanf("%s", current -> name );       /* Read the cat"s name   */
     printf("\nHow old is %s? ", current -> name);
     scanf("%d", &current -> age);        /* Read the cat"s age    */
     printf("\nHow high is %s ( in hands )? ", current -> name);
     scanf("%d", &current -> height);     /* Read the cat"s height */
     printf("\nWho is %s"s father? ", current -> name);
     scanf("%s", current -> father);      /* Get the father"s name   */
     printf("\nWho is %s"s mother? ", current -> name);
     scanf("%s", current -> mother);      /* Get the mother"s name   */
     current -> next = NULL;   /* In case its the last cat...*/
     last = current;           /* Save address of last cat   */
   }
   while(current != NULL)      /* Output cat data in reverse order */
   {
     printf("\n\n%s is %d years old, %d hands high,",
               current->name, current->age, current->height);
     printf(" and has %s and %s as parents.", current->father,
                                            current->mother);
     last = current;      /* Save pointer to enable memory to be freed */
     current = current->previous; /* current points to previous in list */
     free(last);                 /* Free memory for the cat we output */
   }
}


Exercising the horses: Structure array declaration

#include <stdio.h>
#include <ctype.h>
struct cat
{
     int age;
     int height;
     char name[20];
     char father[20];
     char mother[20];
};

int main()
{
   struct cat myCat[50];
   int hcount = 0;
   int i = 0;
   char test = "\0";
   for(hcount = 0; hcount < 50 ; hcount++ )
   {
     printf("\nDo you want to enter details of a%s cat (Y or N)? ", hcount?"nother " : "" );
     scanf(" %c", &test );
     if(tolower(test) == "n")
       break;
     printf("\nEnter the name of the cat: " );
     scanf("%s", myCat[hcount].name );
     printf("\nHow old is %s? ", myCat[hcount].name );
     scanf("%d", &myCat[hcount].age );
     printf("\nHow high is %s ( in hands )? ", myCat[hcount].name );
     scanf("%d", &myCat[hcount].height );
     printf("\nWho is %s"s father? ", myCat[hcount].name );
     scanf("%s", myCat[hcount].father );
     printf("\nWho is %s"s mother? ", myCat[hcount].name );
     scanf("%s", myCat[hcount].mother );
   }
   for (i = 0 ; i < hcount ; i++ )
   {
     printf("\n\n%s is %d years old, %d hands high,",myCat[i].name, myCat[i].age, myCat[i].height);
     printf(" and has %s and %s as parents.", myCat[i].father,myCat[i].mother );
   }
}


Using a linked list of structures representing a person"s name

/*
Beginning C, Third Edition
 By Ivor Horton
 ISBN: 1-59059-253-0
 Published: Apr 2004
 Publisher: apress
*/

/*
   You could link the PhoneRecord structures in a list by adding a pointer member.
   I chose to define a Node structure that is a node in a linked list. Each Node 
   structure will contain a pointer to a PhoneRecord structure and a pointer to
   the next Node structure. Memory for Node and PhoneRecord structures are allocated
   dynamically. You could extend this to allocate memory for names and numbers too.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FIRST_NAME_LEN  31
#define SECOND_NAME_LEN 51
#define NUMBER_LEN      16
#define TRUE             1
#define FALSE            0
/* Structure defining a name */
struct Name
{
  char firstname[FIRST_NAME_LEN];
  char secondname[SECOND_NAME_LEN];
};
/* Structure defining a phone record */
struct PhoneRecord
{
  struct Name name;
  char number[NUMBER_LEN];
};
/* Structure defining a node in a linked list of PhoneRecord structures */
struct Node
{
  struct PhoneRecord *pRecord;     /* Pointer to a PhoneRecord structure   */
  struct Node *pNext;              /* Pointer to the next node in the list */
};
struct Name read_name();                /* Read a name from the keyboard      */               
void show(struct PhoneRecord *pRecord); /* Output a phone record              */
int has_name(struct PhoneRecord record, struct Name name); /* Test for a name */
struct Node* create_node();             /* Create a new list node             */
struct PhoneRecord* create_record();    /* Create a new phone record          */
void insert_node(struct Node *pNode);   /* Insert a node in the list          */
int compare_records(struct PhoneRecord *pFirst, struct PhoneRecord *pSecond);  /* Compare records */
int compare_names(struct Name first, struct Name second); /* Compare two names                     */
void list_numbers(struct Name name);    /* List all numbers for a Name structure */
struct Node *pStart = NULL;
void main()
{
  char answer = "n";
  struct Node *pNode = NULL;                /* Pointer to a list node              */
  struct PhoneRecord *pRecord = NULL;       /* Pointer to a PhoneRecord structure  */
  int found = FALSE;                        /* Records when a name has been found  */
  int i = 0;                                /* Loop control variable               */
 
  /* Read an arbitrary number of phone records from the keyboard */  
  do
  {
    insert_node(create_node());      /* Create and insert new node */
    printf("Do you want to enter another(y or n)?: ");
    scanf(" %c", &answer);
  }while(tolower(answer) == "y");
  /* Search the list of phone records for a number */
  do
  {
    printf("\nEnter a name for which you want the number.");
    list_numbers(read_name());
    printf("Do you want to search for another (y or n)? ");
    scanf(" %c" , &answer);
  }while(tolower(answer) == "y");
  /* List all the records in the linked list */
  pNode = pStart;
  do
  {
    show(pNode->pRecord);
  }while((pNode = pNode->pNext) != 0);
  printf("\n");
  /* Don"t forget to free the memory! */
  pNode = pStart;
  do
  {
    free(pNode->pRecord);    /* Free memory for the record from the current node */
    pStart = pNode;          /* Save current node address                        */
    pNode = pNode->pNext;    /* Get next node address                            */
    free(pStart);            /* Free memory for the current node                 */
  }while((pNode = pNode->pNext) != 0);
}
/* Read a name from the keyboard and store in a structure */
struct Name read_name()
{
  unsigned long inches = 0;
  struct Name name;
    printf("\nEnter a first name: ");
    scanf(" %s", &name.firstname);
    printf("Enter a second name: ");
    scanf(" %s", &name.secondname);
  return name;
}
/* Output a record */
void show(struct PhoneRecord *pRecord)
{
  printf("\n%s %s   %s", pRecord->name.firstname, pRecord->name.secondname, pRecord->number);
}
int has_name(struct PhoneRecord record, struct Name name)
{
  return (strcmp(name.firstname, record.name.firstname)==0 && strcmp(name.secondname, record.name.secondname)==0);
}
/* Create a new list node */
struct Node* create_node()
{
  struct Node *pNode = NULL;                         /* Pointer to the new node                 */
  pNode = (struct Node*)malloc(sizeof(struct Node)); /* Allocate memory for node                */
  pNode->pNext = NULL;                               /* No next node yet                        */
  pNode->pRecord = create_record();                  /* Create record and store address in node */
  return pNode;
}
/* Create a new phone record    */
struct PhoneRecord* create_record() 
{
  struct PhoneRecord *pRecord = NULL;             /* Pointer to the new record */
  pRecord = (struct PhoneRecord*)malloc(sizeof(struct PhoneRecord)); /* Allocate memory */
  pRecord->name = read_name();                    /* Read the name             */      
  /* Get the number for the name */
  printf("Enter the number for this name: ");
  scanf(" %[ 0123456789]",pRecord->number);       /* Read the number - including spaces */
  return pRecord;                                 /* Return the address of the record   */
}
/*
  Compare two PhoneRecord structures
  Returns -1 if the name for the first is < name for the second
  Returns  0 if the name for the first is equal to the name for the second
  Returns +1 if the name for the first is > name for the second
*/
int compare_records(struct PhoneRecord *pFirst, struct PhoneRecord *pSecond)
{
  return compare_names(pFirst->name, pSecond->name);
}
/* Compare two names
  Returns -1 if the  first is < the second
  Returns  0 if the first is equal to tthe second
  Returns +1 if the first is >  the second
  The comparison is by second name. If second names are equal,
  first names are compared.
*/
int compare_names(struct Name first, struct Name second)
{
  int result = 0;
  result = strcmp(first.secondname,second.secondname);
  return (result != 0 ? result : strcmp(first.firstname,second.firstname));
}
/* Insert a node into the list */
void insert_node(struct Node *pNode)
{
  struct Node *pCurrent = NULL;
  struct Node *pPrevious = NULL;
  struct Node *pTemp = NULL;
  /* Check for empty list */
  if(pStart == NULL)
  {
    pStart = pNode;   /* Store address of the node as the start node */
    return;
  }
  /* Find position to insert the new node */
  pCurrent = pStart;
  while(pCurrent != NULL)
  {
    if(compare_records(pNode->pRecord, pCurrent->pRecord) <= 0)
    {                          /* New node goes before current list node */
      pNode->pNext = pCurrent; /* Set new node next pointer to current   */
      if(pPrevious == NULL)    /* If pCurrent is the first node          */
      {                        
        pNode->pNext = pStart; /* New node next pointer points to current */
        pStart = pNode;        /* New node is the first node              */
      }
      else
      {                           /* Otherwise... */
        pPrevious->pNext = pNode; /* Previous node next pointer points to new node */
        pNode->pNext = pCurrent;  /* New node next pointer points to current       */
      }
      return;
    }
    pPrevious = pCurrent;         /* Previous node will be the current node */
    pCurrent = pCurrent->pNext;   /* Current node is now the next node      */   
  }
  /* If we reach here, add pNode to the end */
  pPrevious->pNext = pNode;
}
/* List the numbers for a name */
void list_numbers(struct Name name)
{
  struct Node *pNode = NULL;
  int found = FALSE;
  int result = 0;
  /* Go through the list comparing names */
  pNode = pStart;
  while(pNode != NULL)
  {
    result = compare_names(name, pNode->pRecord->name);
    if(result == 0)
    {
      if(!found)                                    /* If this is the first time      */
      {
        found = TRUE;                               /* Reset found flag               */
        printf("The numbers for this name are:\n"); /* and output the heading         */
      }
      printf("%s\n", pNode->pRecord->number);       /* Output the number for the name */
    }
   else if(result < 0)                              /* If name comes before current   */
      break;                                        /* we are done                    */
    pNode = pNode->pNext;                           /* Otherwise move to next node    */
  }
  if(!found)                                         /* If the name was not found */
    printf("No numbers found for this name.\n");     /* Say so                    */
}