Добавить элемент в список и удалить его - C (СИ)
Формулировка задачи:
Есть уже готовая программа, но она написана для структуры с одним полем, а нужно как-то её переделать для структуры с четырьмя полями... Уже неделю мучаюсь, но кажется я дуб.. Нужно всего-то добавить элемент в список, удалить и выйти, но для одного поля еще понятно, но как туда запихнуть больше чем одно поле?
Буду очень благодарна, если кто сможет помочь.
Вообще дана программа для такой структуры, а нужно модифицировать в структуру Покупатель, которая состоит из:
1) ФИО
2) Дом. адрес
3) Номер телефона
4) Номер кредитной карты
Пожалуйста, откликнитесь на зов о помощиии
#include <stdio.h>
#include<stdlib.h>
struct list
{
char book;
struct list *next;
};
typedef struct list ListNode; (чтобы было несколько таких шаблонов?)
typedef ListNode *ListNodePtr; (указатель на структуру, зачем он?)
void insert (ListNodePtr*, char);
char del (ListNodePtr*, char);
int IsEmpty (ListNodePtr);
void printList (ListNodePtr);
void instructions (void); типо меню?
int main()
{
ListNodePtr start = NULL; // что за старт?
int choice;
char elem;
instructions();
printf("?");
scanf("%d", &choice);
while (choice != 3)
{
switch (choice)
{
case 1:
printf("Enter an character: ");
scanf("\n%c", &elem);
insert(&start, elem);
printList(start);
break;
case 2:
if (!IsEmpty(start))
{
printf("Enter character to be deleted:");
scanf("\n%c", &elem);
if(del(&start,elem))
{ printf("%c deleted.\n", elem);
printList(start); }
else
printf("%c not found.\n", elem);
}
else
printf("List is empty.\n");
break;
default:
printf("Invalid choice.\n");
instructions();
break;
}
printf("?");
scanf("%d", &choice);
}
printf("End of run.\n");
return 0;
}
void instructions (void)
{
printf("Enter choice:\n"
"1. insert an element into the list.\n"
"2. delete an element from the list.\n"
"3. end program.\n");
}
void insert (ListNodePtr *s, char value)
{
ListNodePtr newP, previous, current;
newP = (ListNodePtr)malloc(sizeof(ListNode));
if(newP!=NULL)
{
newP->book = value;
newP->next=NULL;
previous=NULL;
current = *s;
while (current!=NULL && value>current->book)
{ previous = current;
current = current->next; }
if(previous==NULL)
{ newP->next=*s;
*s = newP; }
else
{ previous->next=newP;
newP->next=current; }
}
else
printf("%c not inserted. No memory available.\n", value);
}
char del (ListNodePtr *s, char value)
{
ListNodePtr previous, current, temp;
if (value==(*s)->book)
{
temp = *s;
*s = (*s)->next;
free(temp);
return value;
}
else
{ previous = *s;
current = (*s)->next;
while (current!=NULL && current->book!=value)
{
previous = current;
current = current->next;
}
if (current!=NULL)
{ temp = current;
previous->next=current->next;
free(temp);
return value; }
}
return '\0';
}
int IsEmpty(ListNodePtr s)
{
return s==NULL;
}
void printList(ListNodePtr current)
{
if (current == NULL)
printf ("The list is empty.\n");
else
{ printf("The list is:\n");
while (current!=NULL)
{ printf("%c-->", current->book);
current=current->next; }
printf("NULL\n");
}
}Решение задачи: «Добавить элемент в список и удалить его»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* вспомогательная функция для создания копии строки в динамической памяти
аналог strdup() из BSD 4, напрочь отсутствующей в таких замечательных компиляторах,
как cl из MSVS или bcc из Borland TurboC.
возвращает указатель на строку или NULL при ошибке
требует очистки памяти функцией free() */
char * clonestr(const char * origin) {
char * ptr;
if ( ! origin || ! ( ptr = malloc(strlen(origin) + 1) ) )
return NULL;
return strcpy(ptr, origin);
}
/* структура buyer (покупатель), функции, константы, etc... */
typedef struct BUYER {
char * name;
char * address;
char * phone;
char * card;
} buyer_t;
/* конструктор */
buyer_t * new_buyer(const char * name, const char * address, const char * phone, const char * card) {
buyer_t * buyer = malloc(sizeof(buyer_t));
if ( ! buyer )
return NULL;
buyer->name = clonestr(name);
buyer->address = clonestr(address);
buyer->phone = clonestr(phone);
buyer->card = clonestr(card);
return buyer;
}
/* деструктор, указатель на объект не может быть NULL */
void del_buyer(void * b) {
buyer_t * buyer = (buyer_t*)b;
assert(buyer);
free(buyer->name);
free(buyer->address);
free(buyer->phone);
free(buyer->card);
free(buyer);
}
/* функция для сравнения двух объектов по имени, за тем по адресу и т.д.
если у одного из объектов или у обоих одно из полей равно NULL, сравнение по этому полю пропускается
на входе два указателя на void, которые приводятся к buyer_t*
функция возвращает отрицательное число, 0 или положительное, если первый объект "меньше", "равен" или "больше" второго */
int compare_buyers(const void * a, const void * b) {
buyer_t * buyerA = (buyer_t*)a;
buyer_t * buyerB = (buyer_t*)b;
int cmp = 0;
assert(buyerA && buyerB);
if ( buyerA->name && buyerB->name && ( cmp = strcmp(buyerA->name, buyerB->name) ) )
return cmp;
if ( buyerA->address && buyerB->address && ( cmp = strcmp(buyerA->address, buyerB->address) ) )
return cmp;
if ( buyerA->phone && buyerB->phone && ( cmp = strcmp(buyerA->phone, buyerB->phone) ) )
return cmp;
if ( buyerA->card && buyerB->card && ( cmp = strcmp(buyerA->card, buyerB->card) ) )
return cmp;
return 0;
}
/* функция для вывода информации о покупателе в строку на экран */
/* определение ширины полей */
#define NAME_WIDTH (20)
#define ADDRESS_WIDTH (20)
#define PHONE_WIDTH (15)
#define CARD_WIDTH (15)
void print_buyer(const void * b) {
buyer_t * buyer = (buyer_t*)b;
assert(buyer);
printf("%-*s %-*s %-*s %-*s\n", NAME_WIDTH, buyer->name, ADDRESS_WIDTH, buyer->address, PHONE_WIDTH, buyer->phone, CARD_WIDTH, buyer->card);
}
/* строка почти как в паскале */
typedef char string_t[256];
#define get_string(s) ( scanf("%255[^\n]%*c", (s)) == 1 )
/* функция для создания нового объекта с чтением данных с консоли
возвращает указатель на объект структуры buyer в динамической памяти
или NULL при ошибке */
buyer_t * input_buyer(void) {
string_t name, address, phone, card;
if ( printf("Name: ") && get_string(name) && printf("Address: ") &&
get_string(address) && printf("Phone: ") && get_string(phone) && printf("Card: ") && get_string(card) )
return new_buyer(name, address, phone, card);
else
return NULL;
}
/**********************************************************************************************************************/
/* двусвязанный список и всё, что с ним связанно */
typedef void (*data_destructor_t)(void*);
typedef int (*data_comparator_t)(const void*, const void*);
typedef void (*data_user_t)(const void*);
/* узел в списке */
typedef struct NODE {
void * data;
struct NODE * prev;
struct NODE * next;
} node_t;
/* конструктор, принимает указатель на данные */
node_t * new_node(void * data) {
node_t * node = malloc(sizeof(node_t));
if ( ! node )
return NULL;
node->data = data;
node->prev = NULL;
node->next = NULL;
return node;
}
/* деструктор, принимает указатель на узел и функцию-деструктор данных */
void del_node(node_t * node, data_destructor_t destructor) {
assert(node);
destructor(node->data);
free(node);
}
/* обмен данными в узлах */
void swap_nodes(node_t * a, node_t * b) {
void * data = a->data;
a->data = b->data;
b->data = data;
}
/* собственно список */
typedef struct LIST {
node_t * first;
node_t * last;
} list_t;
/* конструктор */
list_t * new_list(void) {
list_t * list = malloc(sizeof(list_t));
if ( ! list )
return NULL;
list->first = NULL;
list->last = NULL;
return list;
}
void del_list(list_t * list, data_destructor_t data_destructor) {
assert(list);
while ( list->first ) {
list->last = list->first->next;
del_node(list->first, data_destructor);
list->first = list->last;
}
free(list);
}
/* поиск данных по образцу */
void * find_data(list_t * list, const void * data, data_comparator_t comparator) {
node_t * node;
for ( node = list->first; node; node = node->next )
if ( comparator(node->data, data) == 0 )
return node->data;
return NULL;
}
/* удаление данных по образцу */
void del_data(list_t * list, const void * data, data_comparator_t comparator, data_destructor_t destructor) {
node_t * node;
for ( node = list->first; node; node = node->next )
if ( comparator(node->data, data) == 0 )
break;
if ( node ) {
if ( node == list->first )
list->first = list->first->next;
if ( node == list->last )
list->last = list->last->prev;
if ( node->prev )
node->prev->next = node->next;
if ( node->next )
node->next->prev = node->prev;
del_node(node, destructor);
}
}
/* вставка данных в лист, 0 - удачно, -1 - ошибка */
int push_data(list_t * list, void * data) {
node_t * node = new_node(data);
if ( ! node )
return -1;
if ( ! list->first )
list->first = node;
else {
list->last->next = node;
node->prev = list->last;
}
list->last = node;
return 0;
}
node_t * top_data_node(node_t * startNode, data_comparator_t comparator) {
node_t * topNode = startNode;
assert(topNode);
while ( startNode->next ) {
startNode = startNode->next;
if ( comparator(startNode->data, topNode->data) < 0 )
topNode = startNode;
}
return topNode;
}
void sort_list(list_t * list, data_comparator_t comparator) {
node_t * startNode, * topNode;
for ( startNode = list->first; startNode && startNode->next; startNode = startNode->next )
if ( ( topNode = top_data_node(startNode, comparator) ) != startNode )
swap_nodes(startNode, topNode);
}
void for_each(list_t * list, data_user_t func) {
node_t * node;
for ( node = list->first; node; node = node->next )
func(node->data);
}
/********************************************************************************************************/
/* Основная программа */
#define SEPARATOR "**********************************************************************"
int menu(void) {
int ret;
printf("%s\n1 - add buyer\n2 - show buyers\n3 - sort buyers\n4 - delete buyer\n0 - exit\n> ", SEPARATOR);
if ( scanf("%d%*c", &ret) != 1 )
return -1;
printf("%s\n", SEPARATOR);
return ret;
}
int main(void) {
list_t * list;
int action;
assert(list = new_list());
while ( action = menu() ) {
switch ( action ) {
case 1 : {
buyer_t * buyer = input_buyer();
if ( ! buyer ) {
fprintf(stderr, "Memory error!\n");
exit(1);
}
if ( push_data(list, buyer) ) {
fprintf(stderr, "Add data error!\n");
exit(1);
}
printf("Ok\n");
break;
}
case 2 :
for_each(list, print_buyer);
break;
case 3 :
sort_list(list, compare_buyers);
printf("Ok\n");
break;
case 4 : {
string_t name;
buyer_t * buyer;
printf("Name of buyer to delete: ");
if ( ! get_string(name) ) {
fprintf(stderr, "Input error!\n");
break;
}
if ( ! ( buyer = new_buyer(name, NULL, NULL, NULL) ) ) {
fprintf(stderr, "Memory error!\n");
exit(1);
}
del_data(list, (const void*)buyer, compare_buyers, del_buyer);
printf("Ok\n");
break;
}
case -1 : {
char c;
fprintf(stderr, "Menu error! Cleaning input... ");
while ( scanf("%c", &c) == 1 && c != '\n' )
;
fprintf(stderr, "Ok\n");
break;
}
default :
fprintf(stderr, "Wrong choice!\n");
break;
}
}
del_list(list, del_buyer);
exit(0);
}