C/Structure/Structure Array
Содержание
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", ¤t -> age); /* Read the cat"s age */
printf("\nHow high is %s ( in hands )? ", current -> name);
scanf("%d", ¤t -> 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 */
}