-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrevFileWordWise.c
More file actions
228 lines (206 loc) · 6.42 KB
/
revFileWordWise.c
File metadata and controls
228 lines (206 loc) · 6.42 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
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#define STEPSIZE 10
#define LINEWIDTH 80
#define MAX_FILENAME_SIZE 10
/*********************************************
* reverse
* - Given a word, this function will reverse
* the word inplace.
*
* input:- start & end ptrs of the word
*********************************************/
void reverse(char *wordBegin, char *wordEnd)
{
char temp;
while(wordBegin < wordEnd) {
temp = *wordBegin;
*wordBegin = *wordEnd;
*wordEnd = temp;
wordBegin++;
wordEnd--;
}
return;
}
/*****************************************************
* reverseLine
* - This function achieves word wise reversal.
* Given a line, this function will form a word
* and will reverse the word within the line string.
* After reversal of each word, it will reverse the
* complete line.
*
* input:- char* pointing to the line string
*****************************************************/
void reverseLine(char *str) {
char *charIterator = str;
char *wordStart = str;
while(*charIterator) {
charIterator++;
if (*charIterator == ' ' || *charIterator == '\0') {
reverse(wordStart, charIterator-1);
if (*charIterator == ' ') {
wordStart = charIterator + 1;
}
}
}
reverse(str, charIterator - 1);
}
/*************************************************************
* writeToScratchFile
* - This function forms the intermediate scratch files.
* Lets say the input file had 100 lines and our stepsize
* is 10 lines. So we will reverse 10 lines in a word-wise
* manner and send the array of pointers to this function.
* Given the lines, this function will print the lines from
* the last. The resultant scratch file will be merged to
* form a big output file, containing the output in required
* format.
*
* input:- collection of lines, scratchfileNum, number of lines
* in the collection
**************************************************************/
void writeToScratchFile(char *lines[STEPSIZE],
char *scratchFileName,
int numLines)
{
FILE *scratchfp;
scratchfp = fopen(scratchFileName, "w");
if (!scratchfp) {
printf("unable to open scratch file");
return;
}
while(numLines--) {
fprintf(scratchfp, lines[numLines]);
memset(lines[numLines], 0, sizeof(char) * LINEWIDTH);
}
fclose(scratchfp);
}
/*************************************************************
* combineScratchToOutput
* - This function merges the scratch files formed in descending
* order. This means the file containing the last chunk, will
* be merged first.
*
* input:- number of scratch files to merge.
**************************************************************/
void combineScratchToOutput(int numScratchFiles)
{
FILE *outfp;
FILE *scratchfp;
char scratchFileName[MAX_FILENAME_SIZE];
char line[LINEWIDTH];
outfp = fopen("output.txt", "w");
if (!outfp) {
printf("unable to open output file");
}
while(numScratchFiles--) {
memset(scratchFileName, 0, sizeof(char) * MAX_FILENAME_SIZE);
sprintf(scratchFileName, "%d.txt", numScratchFiles);
scratchfp = fopen(scratchFileName, "r");
if (!scratchfp) {
printf("unable to open scratch file");
exit(0);
}
while (fgets(line, LINEWIDTH, scratchfp)) {
fprintf(outfp, line);
memset(line, 0, sizeof(char) * LINEWIDTH);
}
fclose(scratchfp);
}
fclose(outfp);
}
/*******************************************************************
* main
* - This function follows the following logic.
* 1. Given a file with N lines.
* 2. Say,We cannot read N lines at once, but can read 10 lines.
* 3. So we will prepare scratch (N/10)+1 files with 10 lines each.
* 4. In the end we will merge the 10 scratch files.
*
* Scratch files:-
* 1. Lets say we have total 100 lines.
* 2. So we will prepare 10 scratch files with 10 lines each.
* 3. Here each file will contain lines in:-
* 3.1 descending order, i.e. line 10th will come before 9th,
* 9th before 8th and so on.
* 3.2 Also each line will be reversed word wise.
* 4. Intermediate output will be like 0.txt, 1.txt....9.txt
*
* Combining to form the output:-
* 1. Once we have files from 0.txt to 9.txt containing lines
* reversed in a word-wise manner, we start merging with last
* file onwards.
* 2. So contents of 9.txt will come first, followed by 8.txt
* and so on.
* 3. output.txt is our required file.
*
* input:- None
**************************************************************/
int main()
{
FILE *inpfp;
char *lines[STEPSIZE];
char *line;
int i, len;
int numLines = 0;
int iterations = 0;
char outputFileName[MAX_FILENAME_SIZE];
line = (char *)malloc(sizeof(char) * LINEWIDTH);
if (!line) {
printf("memory allocation failure");
goto cleanup;
}
memset(line, 0, sizeof(char) * LINEWIDTH);
for (i = 0;i < STEPSIZE; i++) {
lines[i] = (char *)malloc(sizeof(char) * LINEWIDTH);
if (!lines[i]) {
printf("memory allocation failure");
goto cleanup;
}
memset(lines[i], 0, sizeof(char) * LINEWIDTH);
}
inpfp = fopen("input.txt", "r");
if (!inpfp) {
printf("unable to open input file");
goto cleanup;
}
while (fgets(line, LINEWIDTH, inpfp)) {
len = strlen(line);
line[len-1] = '\0';
reverseLine(line);
line[len-1] = '\n';
line[len] = '\0';
memset(lines[numLines], 0, sizeof(char) * LINEWIDTH);
strncpy(lines[numLines++], line, len);
memset(line, 0, sizeof(char) * LINEWIDTH);
if (numLines == STEPSIZE) {
memset(outputFileName, 0, sizeof(char) * MAX_FILENAME_SIZE);
sprintf(outputFileName, "%d.txt", iterations++);
writeToScratchFile(lines, outputFileName, numLines);
numLines = 0;
}
}
if (numLines > 0) {
memset(outputFileName, 0, sizeof(char) * MAX_FILENAME_SIZE);
sprintf(outputFileName, "%d.txt", iterations++);
writeToScratchFile(lines, outputFileName, numLines);
}
fclose(inpfp);
if (iterations > 0) {
combineScratchToOutput(iterations);
}
cleanup:
// no memory leaks!!
if (line) {
free(line);
}
for(i = 0;i < STEPSIZE; i++) {
if (lines[i]) {
free(lines[i]);
}
}
return 0;
}