-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtweets_generator.c
179 lines (169 loc) · 5.01 KB
/
tweets_generator.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
#include <stdlib.h>
#include <stdio.h>
#include "markov_chain.h"
#include <stdbool.h>
#include <string.h>
#include "linked_list.h"
#define FAILED_OPEN_FILE "Error: Failed to open file, make sure you use"\
" absolute path.\n"
#define WRONG_ARGS "Usage: The program require the following parameters\n"\
" 1) Seed number.\n "\
"2) Number of lines to generate.\n "\
"3) Absolute path to file.\n "\
"4) Optional - Number of lines to read from file. If no value is given"\
" read the entire file.\n"
#define ALLOCATION_ERROR_MASSAGE "Allocation failure: Failed to allocate"\
"new memory\n"
#define TWEET_FORMAT "Tweet %d: "
#define READ "r"
#define SPACE_BAR " "
#define END_LINE "\r\n"
#define VALID_ARGS_4 4
#define VALID_ARGS_5 5
#define FULL_READ -1
#define MAX_TWEET_SIZE 1001
#define SUCCESS 0
#define FAILURE 1
#define DECIMAL 10
#define MAX_WORDS_SENTENCE 20
#define DATABASE_SIZE 1
/**
* This function manages the main operations
* @param num_of_tweets Integer representing the desired number of tweets
* to be printed
* @param in_file A pointer to the input file
* @param words_to_read Integer representing the number of words to read from
* the input file
* @return 0 if all operations and allocations was successful, otherwise 1
*/
int
run_main (long num_of_tweets, FILE *in_file, long words_to_read);
/**
* This function generates all the tweets, according to num_of_tweets
* @param markov_chain A pointer to the MarkovChain chain
* @param num_of_tweets Integer representing the number of tweets to print
*/
void generate_all_sequences (MarkovChain *markov_chain, long num_of_tweets);
/**
* This function try to open a file from a given file path
* @param path String representing a file path
* @return Pointer to the file, NULL upon open failed
*/
FILE *try_open_file (char path[]);
/**
* This function reads data from the file fp and insert it to the database
* @param fp Input file
* @param words_to_read Number of words to read from the input file
* @param markov_chain A pointer to MarkovChain struct
* @return 0 upon success, otherwise 1
*/
int fill_database (FILE *fp, int words_to_read, MarkovChain *markov_chain);
int main (int argc, char *argv[])
{
if (argc > VALID_ARGS_5 || argc < VALID_ARGS_4)
{
printf (WRONG_ARGS);
return EXIT_FAILURE;
}
long words_to_read = FULL_READ;
if (argc == VALID_ARGS_5)
{
words_to_read = strtol (argv[4], NULL, DECIMAL);
}
long seed = strtol (argv[1], NULL, DECIMAL);
long num_of_tweets = strtol (argv[2], NULL, DECIMAL);
srand (seed);
FILE *in_file = try_open_file (argv[3]);
if (in_file == NULL)
{
return EXIT_FAILURE;
}
if (run_main (num_of_tweets, in_file, words_to_read) == FAILURE)
{
printf (ALLOCATION_ERROR_MASSAGE);
fclose(in_file);
return EXIT_FAILURE;
}
fclose (in_file);
return EXIT_SUCCESS;
}
// See full documentation above the main function
int run_main (long num_of_tweets, FILE* in_file, long words_to_read)
{
MarkovChain *markov_chain = malloc (sizeof (MarkovChain));
if (markov_chain == NULL)
{
return FAILURE;
}
markov_chain->database = calloc (DATABASE_SIZE, sizeof (LinkedList));
if (markov_chain->database == NULL)
{
free (markov_chain);
return FAILURE;
}
markov_chain->database->size = 0;
if (fill_database (in_file, words_to_read, markov_chain) == FAILURE)
{
free_markov_chain (&markov_chain);
return FAILURE;
}
generate_all_sequences (markov_chain, num_of_tweets);
free_markov_chain (&markov_chain);
return SUCCESS;
}
// See full documentation above the main function
void generate_all_sequences (MarkovChain *markov_chain, long num_of_tweets)
{
int counter = 0;
while (counter < num_of_tweets)
{
printf (TWEET_FORMAT, counter + 1);
generate_random_sequence (markov_chain, NULL, MAX_WORDS_SENTENCE);
counter++;
}
}
// See full documentation above the main function
FILE *try_open_file (char path[])
{
FILE *in_file = fopen (path, READ);
if (in_file == NULL)
{
printf (FAILED_OPEN_FILE);
}
return in_file;
}
// See full documentation above the main function
int fill_database (FILE *fp, int words_to_read, MarkovChain *markov_chain)
{
char buffer[MAX_TWEET_SIZE];
MarkovNode *prev = NULL, *cur = NULL;
int counter = 0;
while (fgets (buffer, MAX_TWEET_SIZE, fp) != NULL)
{
char *word = strtok (buffer, SPACE_BAR);
while (word != NULL)
{
counter++;
word[strcspn (word, END_LINE)] = 0;
cur = add_to_database (markov_chain, word)->data;
if (cur == NULL)
{
return FAILURE;
}
if (prev != NULL)
{
if (add_node_to_counter_list (prev, cur) == false)
{
return FAILURE;
}
}
prev = cur;
if (words_to_read != FULL_READ && counter == words_to_read)
{
return SUCCESS;
}
word = strtok (NULL, SPACE_BAR);
}
}
return SUCCESS;
}