-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLibrary.c
More file actions
484 lines (425 loc) · 12.1 KB
/
Library.c
File metadata and controls
484 lines (425 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STR 32
typedef struct
{
char title[MAX_STR];
char author[MAX_STR];
int yearPub;
} BookType;
typedef struct Node
{
BookType *data;
struct Node *next;
} NodeType;
typedef struct
{
NodeType *head; // points to the fist node
NodeType *tail; // point to the last node
} ListType;
//Prototypes
int initBook(BookType **book);
void initList(ListType *list);
void addByTitle(ListType *list, BookType *newBook);
void addByYear(ListType *list, BookType *newBook);
void copyList(ListType *src, ListType *dest);
void copyByYear(ListType *src, ListType *dest);
void delAuthor(ListType *list, char *name);
void printList(ListType *list);
void cleanupList(ListType *list);
void cleanupData(ListType *list);
int compareBooksByYear(BookType *, BookType *);
void addBook(ListType *, BookType *, int);
void printHead(ListType *list);
void printTail(ListType *list);
int main()
{
//Initiaize variables
BookType *book;
char nameOfAuthor[MAX_STR];
// Allocate memory to lists
ListType *booksByTitle = (ListType *)malloc(sizeof(ListType));
ListType *booksByYear = (ListType *)malloc(sizeof(ListType));
ListType *tmpList = (ListType *)malloc(sizeof(ListType));
// Initialize the lists
initList(booksByTitle);
initList(booksByYear);
initList(tmpList);
// Prompt user for input until they decide to end
while (1)
{
int rc = initBook(&book);
// check is the user wants to end or not
if (rc == 0)
break;
// add the book to the list
addByTitle(booksByTitle, book);
}
printf("*** BOOKS BY TITLE ***\n");
printList(booksByTitle);
// copy the list
copyList(booksByTitle, tmpList);
printf("Enter a author would you like to delete?\n");
fgets(nameOfAuthor, sizeof(nameOfAuthor), stdin);
nameOfAuthor[strlen(nameOfAuthor) - 1] = '\0';
// delete the inputed author
delAuthor(tmpList, nameOfAuthor);
printf("*** TEMP LIST ***\n");
printList(tmpList);
// copy the title list to the year list and print the yesr list
copyByYear(booksByTitle, booksByYear);
printf("*** BOOKS BY TITLE ***\n");
printList(booksByTitle);
printf("*** BOOKS BY YEAR ***\n");
printList(booksByYear);
// clean up data of all the books
cleanupData(booksByTitle);
// clean up the list nodes
cleanupList(booksByTitle);
cleanupList(booksByYear);
cleanupList(tmpList);
// free the the lists
free(booksByTitle);
free(booksByYear);
free(tmpList);
return 0;
}
/*
Function: initBook
Purpose: Initialize the book by prompting to the user and obtaining the information
Parameters:
in: double pointer of a booktype
return: success or faliure value that is represented by a int value
*/
int initBook(BookType **book)
{
char title[MAX_STR];
char author[MAX_STR];
char yearS[MAX_STR];
int year = 0;
// prompt the user for the year of the book
printf("What is the book title?\n");
fgets(title, sizeof(title), stdin);
title[strlen(title) - 1] = '\0';
// checks if the user wants to end
if (strcmp(title, "end") == 0)
{
// Data entry will end
return 0;
}
else
{
// prompt the user for the author of the book
printf("What is the book author?\n");
fgets(author, sizeof(author), stdin);
author[strlen(author) - 1] = '\0';
// prompt the user for the year of the book
printf("What is the year of publication?\n");
fgets(yearS, sizeof(yearS), stdin);
int rc = sscanf(yearS, "%d", &year);
// if they enter a invlid year restart the input process
if (rc == 0)
{
printf("Invalid integer, restarting input.. please try again\n");
return 1;
}
// allocate the memory for each book
*book = (BookType *)malloc(sizeof(BookType));
//return success implying the new book is initialized
strcpy((*book)->title, title);
strcpy((*book)->author, author);
(*book)->yearPub = year;
printf("Success, your book is added\n");
return 1;
}
}
/*
Function: initList
Purpose: to initialize a given list
Parameters:
in: a pointer to a list
return: -
*/
void initList(ListType *list)
{
list->head = NULL;
list->tail = NULL;
}
/*
Function: addByTitle
Purpose: add a book by title to the given list in while maintaing acending order
Parameters:
in: list and book pointer
return: the list with the added book in acending order
*/
void addByTitle(ListType *list, BookType *newBook)
{
NodeType *currNode = list->head;
int pos = 0;
// figure out the position in the list where to add the book
// when currNode is NULL, we will hit the end of the list
while (currNode != NULL)
{
// Compare the given to the book at the current node to find at what position the book should be added
int compareResult = (strcmp(newBook->title, currNode->data->title));
// if the title are the same
if (compareResult == 0 || compareResult < 0)
break;
// continue the loop if the position is not found
pos++;
currNode = currNode->next;
}
// add the book to the list at the given position
addBook(list, newBook, pos);
}
/*
Function: addByYear
Purpose: add a book by year to the given list
Parameters:
in: list and book pointer
return: list with books added by year in decending order
*/
void addByYear(ListType *list, BookType *newBook)
{
NodeType *currNode = list->head;
int pos = 0;
// keep looping until end of the list
while (currNode != NULL)
{
//Compare the given book to the book at the current node
int rc = compareBooksByYear(newBook, currNode->data);
// the position found where the book needs to be added
if (rc == 1)
break;
// position still not found, keep looping
pos++;
currNode = currNode->next;
}
// add the book, to to position found
addBook(list, newBook, pos);
}
/*
Function: copyList
Purpose: copy all of the nodes and data from the source list to the destination list
Parameters:
in: source list pointer and a dest list pointer
return: the destination list with the all the copied data sorted by acending order by title
*/
void copyList(ListType *src, ListType *dest)
{
NodeType *currsrc = src->head;
// while the current list still have data in it
while (currsrc != NULL)
{
// add the book to the dest list
addByTitle(dest, currsrc->data);
//continue looping until all the node are copied
currsrc = currsrc->next;
}
}
/*
Function: copyByYear
Purpose: copy data from the source list to the dist list and order it by year
Parameters:
in: source list pointer and a dest list pointer
return: the dest list with the copies data sorted by dcending order by year
*/
void copyByYear(ListType *src, ListType *dest)
{
NodeType *currsrc;
currsrc = src->head;
// while the current list still have data in it
while (currsrc != NULL)
{
// add the book to the dest list
addByYear(dest, currsrc->data);
//continue looping until all the node are copied
currsrc = currsrc->next;
}
}
/*
Function: delAuthor
Purpose: delete a given from a given list
Parameters:
in: a list and a name pointer
return: a list
*/
void delAuthor(ListType *list, char *name)
{
NodeType *currNode = list->head;
NodeType *prevNode = NULL;
while (currNode != NULL)
{
int res = strcmp(currNode->data->author, name);
if (res == 0) // did find author's book that is to be deleted
{
NodeType *nodeToBeDeleted = currNode;
if (prevNode == NULL) // currNode must be the head
list->head = currNode->next;
else if (currNode->next == NULL) // currNode must be the tail
{
list->tail = prevNode;
list->tail->next = NULL;
}
else // currNode is in the middle of the list
prevNode->next = currNode->next;
// select next node to check
currNode = currNode->next;
// free the node to be deleted
free(nodeToBeDeleted);
}
else // found the node to be deleted
{
prevNode = currNode;
currNode = currNode->next;
}
}
}
/*
Function: printList
Purpose: print the data of the given list
Parameters:
in: list pointer
return: printed list
*/
void printList(ListType *list)
{
NodeType *currNode = list->head;
printf("BOOK LIST:\n");
while (currNode != NULL)
{
// printf("-----------------------------\n");
printf(" -- %15s\t", currNode->data->title);
printf(" by %15s, \t", currNode->data->author);
printf(" Yr: %d \t \n", currNode->data->yearPub);
currNode = currNode->next;
}
printHead(list);
printTail(list);
}
/*
Function: cleanupList
Purpose: deallocates memory of the nodes of a given list
Parameters:
in: pointer to a list
return: -
*/
void cleanupList(ListType *list)
{
NodeType *currNode = list->head;
NodeType *next;
// iterate through the linked list until the end
while (currNode != NULL)
{
next = currNode->next;
// free the node
free(currNode);
// continue iterating
currNode = next;
}
}
/*
Function: cleanupData
Purpose: deallocate memory of the data of a given list
Parameters:
in: pointer to a list
return: -
*/
void cleanupData(ListType *list)
{
NodeType *currNode, *next;
currNode = list->head;
while (currNode != NULL)
{
next = currNode->next;
free(currNode->data);
currNode = next;
}
}
/*
Function: compareByYear
Purpose: compare the year of two booktypes and find which year is lesser, greater or equal
Parameters:
in: two booktype pointers
return: int value
*/
int compareBooksByYear(BookType *b1, BookType *b2)
{
// find the yearpub of each book
int y1 = b1->yearPub;
int y2 = b2->yearPub;
// compare the two years of the books
if (y1 < y2)
return -1;
else if (y1 > y2)
return 1;
return 0;
}
/*
Function: addBook
Purpose: adds a given book to a given list in a given position
Parameters:
in: a list pointer, booktype pointer and int
return: list with the added book
*/
void addBook(ListType *list, BookType *newBook, int pos)
{
NodeType *newNode;
NodeType *currNode, *prevNode;
int currPos = 0;
// create a new node
newNode = malloc(sizeof(NodeType));
newNode->data = newBook;
newNode->next = NULL;
currNode = list->head;
prevNode = NULL;
while (currNode != NULL)
{
// if the list it already sorted, break
if (currPos == pos)
break;
prevNode = currNode;
currNode = currNode->next;
++currPos;
}
// if the pos is still not found break
if (currPos != pos)
return;
newNode->next = currNode;
// the node is being added to the head
if (prevNode == NULL)
list->head = newNode;
// node added to the anywhere between the head and tail
else
prevNode->next = newNode;
// the node is being added to the tail
if (newNode->next == NULL)
list->tail = newNode;
}
/*
Function: printHead
Purpose: print the data of the head of the given list
Parameters:
in: list pointer
return: printed list
*/
void printHead(ListType *list)
{
printf("--> HEAD is: -- %15s \t", list->head->data->title);
printf(" by%15s \t", list->head->data->author);
printf(" Yr: %d \t \n", list->head->data->yearPub);
}
/*
Function: printTail
Purpose: print the data of the tail of the given list
Parameters:
in: list pointer
return: printed list
*/
void printTail(ListType *list)
{
printf("--> TAIL is: -- %15s \t", list->tail->data->title);
printf(" by%15s, \t", list->tail->data->author);
printf(" Yr: %d \t \n", list->tail->data->yearPub);
}