Skip to content

Instantly share code, notes, and snippets.

@amoshyc
Created October 9, 2014 10:25
Show Gist options
  • Save amoshyc/6e76956ff4772e8645ce to your computer and use it in GitHub Desktop.
Save amoshyc/6e76956ff4772e8645ce to your computer and use it in GitHub Desktop.
DS project 1: ezaddr.c
/*
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