C/Structure/Structure Array

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

A simple mailing list example using an array of structures

<source lang="cpp"> /* 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. */

  1. include <stdio.h>
  2. include <stdlib.h>
  3. 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");

}


      </source>


Daisy chaining the horses both ways

<source lang="cpp">

  1. include <stdio.h>
  2. include <ctype.h>
  3. 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 */
  }

}

      </source>


Exercising the horses: Structure array declaration

<source lang="cpp">

  1. include <stdio.h>
  2. 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 );
  }

}


      </source>


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

<source lang="cpp"> /* 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.
  • /
  1. include <stdio.h>
  2. include <stdlib.h>
  3. include <string.h>
  4. include <ctype.h>
  5. define FIRST_NAME_LEN 31
  6. define SECOND_NAME_LEN 51
  7. define NUMBER_LEN 16
  8. define TRUE 1
  9. 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                    */

}


      </source>