Code:
#include <stdio.h>
#include <string.h>
int size = 0;
// Mail structure to store each e-mail's information
struct mail {
int timeindex;
char month[4];
int date;
char *email;
int msgsize;
char *subject;
};
// Prints out e-mails in order currently stored in pointer
void print(struct mail * m1)
{
int i;
for(i = 0; i < size; i++)
{
printf("%3d ", i + 1);
printf("%s ", (m1 + i) -> month);
printf("%d ", (m1 + i) -> date);
printf("%s ", (m1 + i) -> email);
printf("%d ", (m1 + i) -> msgsize);
printf("%s\n", (m1 + i) -> subject);
}
}
// Sorts emails in ascending order by received time, sender, or message size
void sort(struct mail * m1)
{
int choice, i, pos;
struct mail key;
printf("***Sort Menu***\n");
printf("1. Sort by received time\n");
printf("2. Sort by sender\n");
printf("3. Sort by size\n");
// Read in user choice
do {
printf("Please enter your choice (1-3): ");
scanf("%d", &choice);
} while(choice < 1 || choice > 3);
// Sort in ascending order by time message was received
if(choice == 1)
{
for(i = 0; i < size; i++)
{
for(pos = i; pos < size; pos++)
{
if((m1 + i) -> timeindex > (m1 + pos) -> timeindex)
{
key = *(m1 + i);
*(m1 + i) = *(m1 + pos);
*(m1 + pos) = key;
}
}
}
}
// Sort alphabetically by sender e-mail
else if(choice == 2)
{
for(i = 0; i < size; i++)
{
for(pos = 0; pos < size; i++)
{
if(strcmp((m1 + i) -> email, (m1 + pos) -> email) > 0)
{
key = *(m1 + i);
*(m1 + i) = *(m1 + pos);
*(m1 + pos) = key;
}
}
}
}
// Sort in ascending order by message size
else if(choice == 3)
{
for(i = 0; i < size; i++)
{
for(pos = i; pos < size; pos++);
{
if((m1 + i) -> msgsize > (m1 + pos) -> msgsize)
{
key = *(m1 + i);
*(m1 + i) = *(m1 + pos);
*(m1 + pos) = key;
}
}
}
}
}
void add(struct mail * m1)
{
int i, space, check = 0;
int dtemp, stemp;
char ch, mtemp[4];
char *sendtemp = malloc(20 * sizeof(char));
char *subtemp = malloc(300 * sizeof(char));
struct mail * m1temp;
// Read in month (must be legal three-letter abbreviation)
do {
printf("the month the message is received (format: mmm): ");
scanf("%s", mtemp);
} while(strcmp(mtemp, "Jan") != 0 && strcmp(mtemp, "Feb") != 0 &&
strcmp(mtemp, "Mar") != 0 && strcmp(mtemp, "Apr") != 0 &&
strcmp(mtemp, "May") != 0 && strcmp(mtemp, "Jun") != 0 &&
strcmp(mtemp, "Jul") != 0 && strcmp(mtemp, "Aug") != 0 &&
strcmp(mtemp, "Sep") != 0 && strcmp(mtemp, "Oct") != 0 &&
strcmp(mtemp, "Nov") != 0 && strcmp(mtemp, "Dec") != 0);
// Read in date (must be 1 through 31)
do {
printf("the day the message is received (format: d or dd): ");
scanf("%d", &dtemp);
} while(dtemp < 1 || dtemp > 31);
// Read in size of message (must be positive integer)
do {
printf("the size of the message (format: integer): ");
scanf("%d", &stemp);
} while(stemp < 0);
// Read in sender e-mail (must be single string, no spaces)
do {
space = 0;
printf("the sender of the message (format: no spacing): ");
scanf("%s", sendtemp);
// Check to make sure entry is only one string
while(getchar() != '\n')
space++;
} while(space > 0);
// Read in subject title character by character into a pointer string
i = 0;
printf("the subject of the message (format: no restriction): ");
ch = getchar();
while(ch != '\n')
{
*(subtemp + i) = ch;
i++;
ch = getchar();
}
// Check to make sure entry is not identical to another entry in database
for(i = 0; i < size; i++)
{
if(strcmp(mtemp, (m1 + i) -> month) == 0 &&
dtemp == (m1 + i) -> date &&
stemp == (m1 + i) -> msgsize &&
strcmp(sendtemp, (m1 + i) -> email) == 0 &&
strcmp(subtemp, (m1 + i) -> subject) == 0)
check = 1;
}
// If entry is not identical, add to end of database and update size
if(check == 0)
{
m1 = (struct mail *) realloc(m1, (size + 1) * sizeof(m1temp));
(m1 + size) -> timeindex = size + 1;
for(i = 0; i < 4; i++)
(m1 + size) -> month[i] = mtemp[i];
(m1 + size) -> date = dtemp;
(m1 + size) -> msgsize = stemp;
(m1 + size) -> email = sendtemp;
(m1 + size) -> subject = subtemp;
size++;
printf("The message has been added successfully.\n");
}
// If entry already in database, print out failure message
else
printf("Message add fails. The message exists in the database.\n");
}
void delete(struct mail * m1)
{
int i, index;
// Read in index for deletion
do {
printf("Enter the index of the message to delete (1 to %d): ",
size);
scanf("%d", &index);
} while(index < 1 || index > size);
// Shift all entries after index to the left by one
for(i = index - 1; i < size - 1; i++)
*(m1 + i) = *(m1 + i + 1);
// Free last memory location and update size
free(m1 + size - 1);
size--;
printf("Message has been deleted successfully. ");
printf("There are %d messages left.\n", size);
}
void search(struct mail * m1)
{
char *s1;
int i, k, check, count = 0;
printf("Enter the keyword that you want to search: ");
scanf("%s", s1);
// Loop through entire e-mail database pointer array
for(i = 0; i < size; i++)
{
check = 0;
k = 0;
// While current entry's subject is not at end of string, compare each
// individual word to the keyword
while((m1 + i) -> subject[k] != '\0')
{
int j = 0;
// Increment indices while characters in both strings are equal
// and not at end of subject string
while(s1[j] == (m1 + i) -> subject[k] &&
(m1 + i) -> subject[k] != '\0')
{
j++;
k++;
}
// If length of keyword is equal to j (all characters of word
// match) and it is the end of the currently checked word in
// entry's subject string, increment check
if(strlen(s1) == j && ((m1 + i) -> subject[k] == ' ' ||
(m1 + i) -> subject[k] == '\0'))
check++;
// Increment subject index until beginning of next word in string
while((m1 + i) -> subject[k] != ' ' &&
(m1 + i) -> subject[k] != '\0')
k++;
if((m1 + i) -> subject[k] == ' ')
k++;
}
// If check is larger than 1, print out entry keyword was in
if(check > 0)
{
printf("%3d ", i + 1);
printf("%s ", (m1 + i) -> month);
printf("%d ", (m1 + i) -> date);
printf("%s ", (m1 + i) -> email);
printf("%d ", (m1 + i) -> msgsize);
printf("%s\n", (m1 + i) -> subject);
count++;
}
}
// If keyword not found in any entries, print out keyword not found
if(count == 0)
printf("Keyword %s not found.\n", s1);
}
// Print leave message and exit out of program
void leave()
{
printf("Thanks for using the ENEE 114 Email Database.\n");
printf("Goodbye!\n");
exit(0);
}
int main(int argc, char *argv[])
{
int i, choice;
char ch, temp;
FILE *input;
struct mail *m1, m2;
// Allocate dynamic memory for mail pointer array
m1 = (struct mail *) malloc(sizeof(m2));
// If not enough arguments in command line, print out error
if(argc != 2)
{
printf("Usage: executable input_file\n");
exit(0);
}
input = fopen(argv[1], "r");
// Check to make sure input file opened correctly
if(input == NULL)
{
printf("File %s cannot open!\n", argv[1]);
exit(0);
}
// Store input file e-mail information into mail database pointer array
while(fscanf(input, "%c", &temp) != EOF)
{
i = 0;
// Store time index to indicate when message was added
(m1 + size) -> timeindex = size + 1;
// Store month abbreviation in character by character
(m1 + size) -> month[0] = temp;
fscanf(input, "%c", &((m1 + size) -> month[1]));
fscanf(input, "%c", &((m1 + size) -> month[2]));
(m1 + size) -> month[3] = '\0';
// Store date in
fscanf(input, "%d", &((m1 + size) -> date));
// Allocate memory for e-mail string and store string
(m1 + size) -> email = malloc(20 * sizeof(char));
fscanf(input, "%s", (m1 + size) -> email);
// Store message size in
fscanf(input, "%d", &((m1 + size) -> msgsize));
// Skip blank space
fscanf(input, "%c", &ch);
// Allocate memory for subject string and store in character by
// character until at end of current line
(m1 + size) -> subject = malloc(300 * sizeof(char));
while(fscanf(input, "%c", &ch) != EOF && ch != '\n')
{
*((m1 + size) -> subject + i) = ch;
i++;
}
// Update size and reallocate mail pointer to larger memory location
size++;
m1 = (struct mail *) realloc(m1, (size + 1) * sizeof(m2));
}
// Display menu and call appropriate function for entered choice
printf("Welcome to ENEE 114 Email Database\n");
do {
printf("***Main Menu***\n");
printf("1. Print\n");
printf("2. Sort\n");
printf("3. Add Message\n");
printf("4. Delete Message\n");
printf("5. Keyword Search\n");
printf("6. Exit\n");
printf("\nPlease enter your choice (1-6): ");
scanf("%d", &choice);
switch(choice)
{
case 1: print(m1); break;
case 2: sort(m1); break;
case 3: add(m1); break;
case 4: delete(m1); break;
case 5: search(m1); break;
default: leave(); break;
}
} while(choice != 6);
free(m1);
free(m2);
fclose(input);
return 0;
}