1
+ /*
2
+ IN THIS FILE WE WILL IMPLEMENT ALL THE BASIC FUNCTIONS OF STRING MANIPULATION ON C PROGRAMMING LANGUAGE.
3
+
4
+ */
5
+
6
+ #include <stdio.h>
7
+ #include <stdbool.h>
8
+ #include <assert.h>
9
+ #include <stdlib.h>
10
+
11
+ char toLower (char c );
12
+ char toUpper (char c );
13
+
14
+ void printStr (char * str );
15
+ void copyStr (char * str , char * data );
16
+ void concat (char * dest , char * first_str , char * second_str );
17
+ void split (char * str , int pos , char * rest );
18
+ void splice (char * str , int pos , int charCoutn );
19
+ void slice (char * dest , char * str , int pos , int charCount );
20
+ void trim (char * str , char char_to_trim );
21
+ void replace (char * str , char * sub , char * new_sub );
22
+
23
+ int countWords (char * str , char delemeter );
24
+ int getLength (char * c );
25
+
26
+ bool isEmpty (char * str );
27
+ bool findSubString (char * str , char * sub );
28
+
29
+ int main (void )
30
+ {
31
+ char * sub = malloc (10 * sizeof (char ));
32
+ char * str = malloc (20 * sizeof (char ));
33
+ char * dest = malloc (29 * sizeof (char )); // 10 + 20 -1
34
+
35
+ copyStr (str , "theretherethere" );
36
+
37
+ replace (str , "there" , "body!" );
38
+
39
+ printf ("-----\n" );
40
+ printStr (str );
41
+
42
+ /* deallocation */
43
+
44
+ str != NULL ? free (str ) : true;
45
+ sub != NULL ? free (sub ) : true;
46
+ return 0 ;
47
+ }
48
+
49
+ char toUpper (char c )
50
+ {
51
+ assert ((int )c >= 97 );
52
+ return ((int )c - 32 );
53
+ }
54
+
55
+ char toLower (char c )
56
+ {
57
+ assert ((int )c >= 62 && ((int )c <= 62 + 26 ));
58
+ return ((int )c + 32 );
59
+ }
60
+
61
+ void copyStr (char * str , char * data )
62
+ {
63
+ assert (str != NULL && data != NULL );
64
+
65
+ int counter = 0 ;
66
+
67
+ while (* (data + counter ) != '\0' )
68
+ {
69
+ * (str + counter ) = * (data + counter );
70
+ counter ++ ;
71
+ }
72
+
73
+ * (str + counter ) = '\0' ;
74
+ }
75
+
76
+ void printStr (char * str )
77
+ {
78
+ assert (str != NULL );
79
+
80
+ int counter = 0 ;
81
+ while (* (str + counter ) != '\0' )
82
+ {
83
+ printf ("%c" , * (str + counter ));
84
+ counter ++ ;
85
+ }
86
+ printf ("\n" );
87
+ }
88
+
89
+ bool isEmpty (char * str )
90
+ {
91
+ return (str == NULL || * str == '\0' ? true : false);
92
+ }
93
+
94
+ int getLength (char * str )
95
+ {
96
+ assert (str != NULL );
97
+
98
+ int counter = 0 ;
99
+ while (* (str + counter ) != '\0' )
100
+ {
101
+ counter ++ ;
102
+ }
103
+ return counter ;
104
+ }
105
+
106
+ int countWords (char * str , char delemeter )
107
+ {
108
+ int resault = 0 ;
109
+ bool delemeterMode = true; // this value will track if we've met a delemeter after the last word.
110
+
111
+ for (int i = 0 ; * (str + i ) != '\0' ; ++ i )
112
+ {
113
+ if (* (str + i ) == delemeter )
114
+ {
115
+ delemeterMode = true;
116
+ }
117
+ else
118
+ {
119
+ if (delemeterMode )
120
+ {
121
+ resault ++ ;
122
+ }
123
+ delemeterMode = false;
124
+ }
125
+ }
126
+
127
+ return resault ;
128
+ }
129
+
130
+ void split (char * str , int pos , char * rest )
131
+ {
132
+ assert (!isEmpty (str ));
133
+ assert (rest != NULL );
134
+
135
+ if (pos <= 0 )
136
+ {
137
+ rest = str ;
138
+ }
139
+ if (pos >= getLength (str ))
140
+ {
141
+ return ;
142
+ }
143
+
144
+ copyStr (rest , (str + pos ));
145
+
146
+ * (str + pos ) = '\0' ;
147
+ }
148
+
149
+ bool findSubString (char * str , char * sub )
150
+ {
151
+ assert (str != NULL );
152
+ assert (sub != NULL );
153
+
154
+ if (getLength (str ) < getLength (sub ))
155
+ {
156
+ return false;
157
+ }
158
+
159
+ bool resault = false;
160
+ int counter = 0 ;
161
+
162
+ while (* (sub + counter ) != '\0' )
163
+ {
164
+ if (* (str + counter ) != * (sub + counter ))
165
+ {
166
+ resault = false;
167
+ break ;
168
+ }
169
+ counter ++ ;
170
+ }
171
+
172
+ if (counter == getLength (sub ))
173
+ {
174
+ return true;
175
+ }
176
+
177
+ return resault || findSubString ((str + 1 ), sub );
178
+ }
179
+
180
+ void concat (char * dest , char * first_str , char * second_str )
181
+ {
182
+ assert (dest != NULL );
183
+ assert (first_str != NULL );
184
+ assert (second_str != NULL );
185
+
186
+ copyStr (dest , first_str );
187
+
188
+ char * walker = dest ;
189
+
190
+ while (* (walker ) != '\0' )
191
+ {
192
+ // this is coded this way to be more explicit, we could do +=1;
193
+ walker = & (* (walker + 1 ));
194
+ }
195
+
196
+ copyStr (walker , second_str );
197
+ }
198
+
199
+ void splice (char * str , int pos , int charCount )
200
+ {
201
+ assert (str != NULL );
202
+
203
+ char * walker = str ;
204
+ int counter = 0 ;
205
+
206
+ while (* walker != '\0' && counter < pos )
207
+ {
208
+ walker = & (* (walker + 1 ));
209
+ counter ++ ;
210
+ }
211
+ assert (* walker != '\0' );
212
+
213
+ // keep track of the tial of the list after we will remove the elements
214
+ char * temp = & (* (walker + charCount ));
215
+
216
+ counter = 0 ;
217
+
218
+ while (counter < charCount )
219
+ {
220
+ * (walker + counter ) = '\0' ;
221
+ counter ++ ;
222
+ }
223
+
224
+ // paste the tail of the list at the pos location;
225
+ copyStr (walker , temp );
226
+ }
227
+
228
+ void slice (char * dest , char * str , int pos , int charCount )
229
+ {
230
+ assert (str != NULL );
231
+ assert (dest != NULL );
232
+
233
+ char * walker = str ;
234
+ int counter = 0 ;
235
+
236
+ while (* walker != '\0' && counter < pos )
237
+ {
238
+ walker = & (* (walker + 1 ));
239
+ counter ++ ;
240
+ }
241
+
242
+ assert (* walker != '\0' );
243
+
244
+ counter = 0 ;
245
+
246
+ while (counter < charCount )
247
+ {
248
+ * (dest + counter ) = * (walker + counter );
249
+ counter ++ ;
250
+ }
251
+
252
+ splice (walker , 0 , charCount );
253
+ }
254
+
255
+ void trim (char * str , char char_to_trim )
256
+ {
257
+ assert (str != NULL );
258
+
259
+ char * walker = str ;
260
+
261
+ while (* walker != '\0' )
262
+ {
263
+ if (* walker == char_to_trim )
264
+ {
265
+ * walker = "" ;
266
+ }
267
+ walker = & (* (walker + 1 ));
268
+ }
269
+ }
270
+
271
+ void replace (char * str , char * sub , char * new_sub )
272
+ {
273
+ assert (str != NULL );
274
+ assert (getLength (sub ) == getLength (new_sub ));
275
+
276
+ // this algorithm needs to be recursive,
277
+
278
+ if (getLength (str ) < getLength (sub ))
279
+ return ;
280
+
281
+ bool is_at_beginning = true; // assume that sub is at the beginning of str
282
+
283
+ char * walker = str ;
284
+ int limit = getLength (sub );
285
+ int counter = 0 ;
286
+
287
+ while (* walker != '\0' && counter < limit && is_at_beginning )
288
+ {
289
+ if (* (walker + counter ) != * (sub + counter ))
290
+ is_at_beginning = false;
291
+
292
+ counter ++ ;
293
+ }
294
+
295
+ counter = 0 ;
296
+
297
+ if (is_at_beginning )
298
+ {
299
+ while (* walker != '\0' && counter < limit )
300
+ {
301
+ * (walker + counter ) = * (new_sub + counter );
302
+ counter ++ ;
303
+ }
304
+ replace (str + getLength (sub ), sub , new_sub );
305
+ }
306
+ else
307
+ {
308
+ replace (str + 1 , sub , new_sub );
309
+ }
310
+ }
0 commit comments