-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
124 lines (109 loc) · 4.38 KB
/
main.c
File metadata and controls
124 lines (109 loc) · 4.38 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
/*
* Filename: main.c
* Author: Justin Lee
* Date: 17 October 2019
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include "projStrings.h"
#include "hashTable.c"
/*
* Function Name: main()
* Function Prototype: int main(int argc, char *argv[]);
* Description: The main driver of this program. The main function
* will read in the inputted HTTP header file and return
* the number of times that each header occurs in the file
* Parameters: argc - the number of arguments
* argv - the array containing arguments. namely
* argv[0] will be the program name
* argv[1] will be the path to the input HTTP header file
* Side Effects: -Prints the result to stdout on successfull read and search
* -Prints to stderr if there was an error reading the file or
* with the specified file path
* Return Value: EXIT_FAILURE on error
* EXIT_SUCCESS otherwise
*
*/
int main(int argc, char *argv[]){
//if the number of arguments is incorrect
if(argc != 2) { //we print the usage error message and return
fprintf(stderr, USAGE_MESSAGE);
return EXIT_FAILURE;
}
/* This section equivalent to having a function that takes an input string of
* the file path and returning a pointer to the opened file */
//We will now attempt to build a stat for the specified file
//This is so that we can determine if the file exists, and also that the file is not a directory
errno = 0;
struct stat buf;
stat(argv[1], &buf);
if(errno != 0){ //return error if building stat fails, i.e file does not exist
fprintf(stderr, FILE_DNE);
return EXIT_FAILURE;
}
if(S_ISDIR(buf.st_mode) == 1){ //return error if file is a directory
fprintf(stderr, FILE_DIR);
return EXIT_FAILURE;
}
errno = 0;
//We will now attempt to open the file
FILE *fp = fopen(argv[1], "r");
if(errno != 0){ //returns error if the file cannot be opened
fprintf(stderr, FILE_NOPEN);
return EXIT_FAILURE;
}
/* End returning a FILE pointer *fp */
//Now that the file is open and fp points to it, we can parse the file
//in order to achieve this, we will go line by line through the file
//and we will attempt to extract the header from each line, and
//insert / search for it in a hash table.
//The purpose of the hash table is so that we can keep track of the number
//of occurences and search/insert each word in O(1) time
//My implementation of a HashTable is technically a hash Map
// key = header value = number of occurences
struct HashTable ht;
HashTableMemSet(&ht);
//scan the file line by line, if the file is openable, the program assumes
//it's a valid file of headers. As we scan each line, we are determining
//if each line indeed contains a header, and if it does, it determines if
//we need to increment an existing counter for this header or create
//a new slot in the hashtable
char *line = NULL;
struct Node *temp;
size_t len = 200; //sets a hard 200 byte limitation for each line...
char *colPtr; //searches for the first occurence of ':' to check for header
//assuming the file is formatted correctly, this should work
//only edge case when the first line of the header block has
//a colon in it...
while(getline(&line, &len, fp) != -1){ //scanning line by line of the file
colPtr = strchr(line, ':'); //search for the first occurence of ':'
//the idea being that we can extract the word because it is before ':'
if(colPtr != NULL){
char key[100]; //sets a hard 100 byte limitation for key....
strncpy(key, line, (int)(colPtr - line));
key[(int)(colPtr - line)] = '\0';
temp = search(key, &ht);
if(temp == NULL){
insert(key, &ht);
}
}
}
//at this point, the hashMap is filled, so we need to iterate through the
//elements. also memory is freed here
struct Node *next;
for(int i=0; i<LENGTH; i++){
temp = ht.hashArray[i];
while(temp != NULL){
printf(STR_RESULT, temp->key, temp->occurences);
next = temp->next;
free(temp->key);
free(temp);
temp = next;
}
}
return EXIT_SUCCESS;
}