Created
October 9, 2014 10:25
-
-
Save amoshyc/6e76956ff4772e8645ce to your computer and use it in GitHub Desktop.
DS project 1: ezaddr.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Yu-Cheng Huang 09.24.2014 403410034 | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <ctype.h> | |
int max(const int a, const int b) { | |
return ((a > b) ? a : b); | |
} | |
int max_name = -1; | |
int max_phone = -1; | |
int max_email = -1; | |
int max_dob = -1; | |
typedef enum { false, true } bool; | |
typedef struct | |
{ | |
char* name; | |
char* phone; | |
char* e_mail; | |
char* dob; /* Date of Birth */ | |
} Contact; | |
typedef struct node | |
{ | |
Contact contact; | |
struct node* next; | |
} Node; | |
int comapre_node(const void* a, const void* b) { | |
return strcmp((((Node*) a)->contact).name, (((Node*) b)->contact).name); | |
} | |
bool is_phone(const char* c) { | |
int i = 0; | |
for (; i<strlen(c); i++) | |
if (!isdigit(c[i]) && c[i] != ',' && c[i] != ' ') | |
return false; | |
return true; | |
} | |
Node* new_node(char* inp, const char* delimiters) { | |
Node* n = (Node*) malloc (sizeof(Node)); | |
(n->next) = NULL; | |
(n->contact).name = NULL; | |
(n->contact).phone = NULL; | |
(n->contact).e_mail = NULL; | |
(n->contact).dob = NULL; | |
char* tok = strtok(inp, delimiters); | |
while (tok != NULL) { | |
if (strchr(tok, '@') != NULL) { | |
(n->contact).e_mail = (char*) malloc (sizeof(char) * (strlen(tok)+1)); | |
strcpy((n->contact).e_mail, tok); | |
} | |
else if (strchr(tok, '/') != NULL) { | |
(n->contact).dob = (char*) malloc (sizeof(char) * (strlen(tok)+1)); | |
strcpy((n->contact).dob, tok); | |
} | |
else if (is_phone(tok)) { | |
(n->contact).phone = (char*) malloc (sizeof(char) * (strlen(tok)+1)); | |
strcpy((n->contact).phone, tok); | |
} | |
else { /* Name */ | |
(n->contact).name = (char*) malloc (sizeof(char) * (strlen(tok)+1)); | |
strcpy((n->contact).name, tok); | |
} | |
tok = strtok(NULL, delimiters); | |
} | |
if ((n->contact).name == NULL) { | |
(n->contact).name = (char*) malloc (sizeof(char)*1); | |
strcpy((n->contact).name, ""); | |
} | |
if ((n->contact).phone == NULL) { | |
(n->contact).phone = (char*) malloc (sizeof(char)*1); | |
strcpy((n->contact).phone, ""); | |
} | |
if ((n->contact).e_mail == NULL) { | |
(n->contact).e_mail = (char*) malloc (sizeof(char)*1); | |
strcpy((n->contact).e_mail, ""); | |
} | |
if ((n->contact).dob == NULL) { | |
(n->contact).dob = (char*) malloc (sizeof(char)*1); | |
strcpy((n->contact).dob, ""); | |
} | |
tok = NULL; | |
// free(tok); | |
return n; | |
} | |
void print_node(const Node* curr) { | |
printf("%-*s", max_name+1, (curr->contact).name); | |
printf("%-*s", max_dob+1, (curr->contact).dob); | |
printf("%-*s", max_phone+1, (curr->contact).phone); | |
printf("%-*s", max_email+1, (curr->contact).e_mail); | |
printf("\n"); | |
// printf("%s ", (curr->contact).name); | |
// printf("%s ", (curr->contact).dob); | |
// printf("%s ", (curr->contact).phone); | |
// printf("%s", (curr->contact).e_mail); | |
// printf("\n"); | |
} | |
Node* get_list(const char* filename) { | |
FILE* f = freopen(filename, "r", stdin); | |
if (!f) { | |
printf("IO Error!\n"); | |
return NULL; | |
} | |
Node* head = NULL; | |
Node* prev = NULL; | |
char inp[300]; | |
while (fgets(inp, 300, f) != NULL) { | |
if (inp[strlen(inp)-1] == '\n') | |
inp[strlen(inp)-1] = 0; /*replace the endl*/ | |
Node* curr = new_node(inp, "\t"); | |
if (head == NULL) { | |
head = curr; | |
prev = head; | |
} | |
else { | |
prev->next = curr; | |
prev = curr; | |
} | |
} | |
// free(prev); | |
// free(curr); | |
fclose(f); | |
/* find max length of each field */ | |
max_name = -1; | |
max_phone = -1; | |
max_email = -1; | |
max_dob = -1; | |
Node* curr2 = head; | |
while (curr2 != NULL) { | |
max_name = max(max_name, strlen((curr2->contact).name)); | |
max_phone = max(max_phone, strlen((curr2->contact).phone)); | |
max_email = max(max_email, strlen((curr2->contact).e_mail)); | |
max_dob = max(max_dob, strlen((curr2->contact).dob)); | |
curr2 = curr2->next; | |
} | |
curr2 = NULL; | |
// free(curr2); | |
return head; | |
} | |
void list_data(Node* list) { | |
if(list == NULL) return; | |
Node* idx = list; | |
while (idx != NULL) { | |
print_node(idx); | |
idx = idx->next; | |
} | |
idx = NULL; | |
// free(idx); | |
} | |
void find_and_print(const char* query, Node* list) { | |
if (list == NULL) return; | |
Node* curr = list; | |
bool found = false; | |
while (curr != NULL) { | |
if (strstr((curr->contact).name, query) != NULL || | |
strstr((curr->contact).phone, query) != NULL || | |
strstr((curr->contact).e_mail, query) != NULL || | |
strstr((curr->contact).dob, query) != NULL) { | |
print_node(curr); | |
found = true; | |
} | |
curr = curr->next; | |
} | |
if (found == false) | |
printf("(Not Found!)\n"); | |
curr = NULL; | |
// free(curr); | |
} | |
void sort_and_print(Node* list, const int flag) { | |
/* flag: | |
0: increasing order | |
1: decreasing order | |
*/ | |
if (list == NULL) return; | |
/* find len */ | |
int len = 0; | |
Node* curr = list; | |
while (curr != NULL) { | |
len++; | |
curr = curr->next; | |
} | |
Node* array = (Node*) malloc (sizeof(Node)*len); | |
curr = list; | |
int idx = 0; | |
while (curr != NULL) { | |
array[idx++] = *curr; | |
curr = curr->next; | |
} | |
qsort(array, len, sizeof(Node), comapre_node); | |
if (flag == 0) | |
for (idx=0; idx < len; idx++) | |
print_node((array+idx)); | |
else | |
for (idx=len-1; idx>=0; idx--) | |
print_node((array+idx)); | |
array = NULL; | |
// free(array); | |
curr = NULL; | |
// free(curr); | |
} | |
void update_to_file(char* c, const char* filename) { | |
Node* n = new_node(c, " "); | |
if (strcmp((n->contact).name, "") == 0 || | |
strcmp((n->contact).phone, "") == 0) { | |
printf("Illegal Record!\n"); | |
return; | |
} | |
FILE* f = freopen(filename, "a+", stdout); | |
if (!f) { | |
printf("IO error!\n"); | |
return; | |
} | |
printf("%s", (n->contact).name); | |
if (strcmp((n->contact).dob, "") != 0) | |
printf("\t%s", (n->contact).dob); | |
if (strcmp((n->contact).phone, "") != 0) | |
printf("\t%s", (n->contact).phone); | |
if (strcmp((n->contact).e_mail, "") != 0) | |
printf("\t%s", (n->contact).e_mail); | |
printf("\n"); | |
n = NULL; | |
// free(n); | |
fclose(f); | |
} | |
void print_help() { | |
printf("You should use the following arguments:\n"); | |
printf("%-*s%s\n", 5, "-l", "To list the address records"); | |
printf("%-*s%s\n", 5, "-a", "To add a new record to the addressbook file"); | |
printf("%-*s%s\n", 5, "-f", "To find wanted record by giving a query pattern"); | |
printf("%-*s%s\n", 5, "-s", "To sort the records by Name. The default order is increasing order."); | |
printf(" To make the order be decreasing, add -d option after -s\n"); | |
printf("\n"); | |
printf("Example:\n"); | |
printf(" ezaddrbook -l addr.txt\n\twill print out the address book\n"); | |
printf(" ezaddrbook -f \"john\" addr.txt\n\twill print out those records that contain a match of john\n"); | |
printf(" ezaddrbook -s addr.txt\n\twill sort the data by the Name field and then print out the content.\n"); | |
printf(" ezaddrbook -a \"Mary\" [email protected]\n\twill add a new record to addr.txt\n"); | |
} | |
int main(int argc, char* argv[]) { | |
if (argc <= 2) { | |
print_help(); | |
return 0; | |
} | |
if (strcmp(argv[1], "-l") == 0) { | |
list_data(get_list(argv[2])); | |
} | |
else if (strcmp(argv[1], "-f") == 0) { | |
if (argc != 4) { | |
print_help(); | |
return 0; | |
} | |
find_and_print(argv[2], get_list(argv[3])); | |
} | |
else if (strcmp(argv[1], "-s") == 0) { | |
/* | |
0: increasing order | |
1: decreasing order | |
*/ | |
if (argc == 4) { | |
if (strcmp(argv[2], "-d") == 0) | |
sort_and_print(get_list(argv[3]), 1); | |
else | |
sort_and_print(get_list(argv[3]), 0); | |
} | |
else | |
sort_and_print(get_list(argv[2]), 0); | |
} | |
else if (strcmp(argv[1], "-a") == 0) { | |
if (argc != 4) { | |
print_help(); | |
return 0; | |
} | |
update_to_file(argv[2], argv[3]); | |
} | |
else { | |
print_help(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment