-
Notifications
You must be signed in to change notification settings - Fork 0
/
lpr.c
191 lines (171 loc) · 4.11 KB
/
lpr.c
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
#include "lpr.h"
#include "simulator.h"
// Setting number of buckets to 100 according to the plates.txt file
#define BUCKETS_SIZE 100
size_t buckets = BUCKETS_SIZE;
void item_print(item_t *i)
{
printf("key=%s value=%d", i->key, i->value);
}
// Initialising the hash table to be created
bool htab_init(htab_t *h, size_t n)
{
h->size = n;
h->buckets = (item_t **)calloc(n, sizeof(item_t *));
return h->buckets != 0;
}
size_t djb_hash(char *s)
{
size_t hash = 5381;
int c;
while ((c = *s++) != '\0')
{
// hash = hash * 33 + c
hash = ((hash << 5) + hash) + c;
}
return hash;
}
size_t htab_index(htab_t *h, char *key)
{
return djb_hash(key) % h->size;
}
item_t *htab_bucket(htab_t *h, char *key)
{
return h->buckets[htab_index(h, key)];
}
// Searching the hash table to find a particular key value
item_t *htab_find(htab_t *h, char *key)
{
for (item_t *i = htab_bucket(h, key); i != NULL; i = i->next)
{
if (strcmp(i->key, key) == 0)
{ // found the key
return i;
}
}
return NULL;
}
// Adding values to the hash table
bool htab_add(htab_t *h, char *key, int value)
{
// allocate new item
item_t *newhead = (item_t *)malloc(sizeof(item_t));
if (newhead == NULL)
{
return false;
}
newhead->key = key;
newhead->value = value;
// hash key and place item in appropriate bucket
size_t bucket = htab_index(h, key);
newhead->next = h->buckets[bucket];
h->buckets[bucket] = newhead;
return true;
}
// Printing the hash table created and its values stored
void htab_print(htab_t *h)
{
printf("hash table with %ld buckets\n", h->size);
for (size_t i = 0; i < h->size; ++i)
{
printf("bucket %ld: ", i);
if (h->buckets[i] == NULL)
{
printf("empty\n");
}
else
{
for (item_t *j = h->buckets[i]; j != NULL; j = j->next)
{
item_print(j);
if (j->next != NULL)
{
printf(" -> ");
}
}
printf("\n");
}
}
}
// Destroying the hash table created
void htab_destroy(htab_t *h)
{
// free linked lists
for (size_t i = 0; i < h->size; ++i)
{
item_t *bucket = h->buckets[i];
while (bucket != NULL)
{
item_t *next = bucket->next;
free(bucket);
bucket = next;
}
}
// free buckets array
free(h->buckets);
h->buckets = NULL;
h->size = 0;
}
// Initialise the hash table for plates to be stored
int platesInit( ) {
if (!htab_init(&h, buckets))
{
printf("failed to initialise hash table\n");
return EXIT_FAILURE;
}
return 0;
}
// Read the file and add each line to the hash table
void readPlates( const char * filename, const char * mode ) {
platesInit();
// Opening file
FILE* fp;
int count = 0;
fp = fopen(filename, mode);
if (fp == NULL) {
perror("Failed: ");
return;
}
// Going through each line of the file
char buffer[256];
while (fgets(buffer, sizeof buffer, fp)) {
buffer[strcspn(buffer, "\n")] = 0;
char *plate = (char *)malloc(sizeof(char)*100);
strcpy(plate, buffer);
htab_add(&h, plate, count);
count++;
}
// Closing file
fclose(fp);
return;
}
// Reading the plates.txt file to retrieve a license plate to be used
bool randLine ( char *plate ) {
// Generate random line to get a plate from
int line;
line = generateInRange( 1, 100 );
// Opening file
FILE *fp = fopen("plates.txt", "r");
int count = 0;
if ( fp == NULL) {
return false;
}
// Read through each line of file
char buffer[256];
while (fgets(buffer, sizeof buffer, fp) != NULL)
{
buffer[strcspn(buffer, "\n")] = 0;
if (count == line)
{
// Close file
fclose(fp);
strcpy(plate, buffer);
return true;
}
else
{
count++;
}
}
return false;
}