-
Notifications
You must be signed in to change notification settings - Fork 0
/
mystring.h
521 lines (478 loc) · 17.9 KB
/
mystring.h
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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
/*
MYSTRING opaque object interface
*/
#ifndef MYSTRING_H
#define MYSTRING_H
#include <stdio.h>
/*****************************************************************************
* The opaque object type provided by mystring_init_default and
* mystring_init_c_string, and provided to the other functions in this
* module.
*****************************************************************************/
typedef struct _MYSTRING *MYSTRING;
/****************************************************************************
* Status values returned by some functions in this module
****************************************************************************/
enum mystring_status {MYSTRING_STATUS_ERROR, MYSTRING_STATUS_SUCCESS};
typedef enum mystring_status MyString_Status;
/****************************************************************************
* The starting capacity for a default MYSTRING instance
****************************************************************************/
#define MYSTRING_STARTING_CAPACITY 7
#include <stdio.h>
void string_assignment(void** left, void* right);
void string_destructor(void** object);
void mystring_sort(MYSTRING hString);
int mystring_contains(MYSTRING hString, char c, int index);
int mystring_compare(MYSTRING left, MYSTRING right);
/*****************************************************************************
* Create a "default" new MYSTRING opaque object (with no initial data)
*
*
* @return
* upon failure: NULL
* The function fails if memory to complete the operation is not available
*
* upon success:
* A MYSTRING handle to a default string object that has:
* size = 0
* capacity = MYSTRING_STARTING_CAPACITY
****************************************************************************/
MYSTRING mystring_init_default(void);
/*****************************************************************************
* Create a new MYSTRING opaque object from a given c-string (null terminated
* array).
*
* @param c_string
* The null-terminated C string used to initialize the new MYSTRING
* object.
*
* @return
* upon failure: NULL
* The function fails if memory to complete the operation is not available
*
* upon success:
* A MYSTRING handle to a string object representing the given c-string
* that has:
* size = number of characters in the initializer, c_string,
* not including its null terminator
* capacity = number of characters in the initializer, c_string,
* not including its null terminator
*
* @note
* Internally, the string is NOT stored with a null terminator. Only enough
* memory for the string's length (not including its null terminator) is
* allocated, and the c_string's characters are copied into that memory.
****************************************************************************/
MYSTRING mystring_init_c_string(const char * const c_string);
/*****************************************************************************
* Destroy a MYSTRING opaque object and set the handle to NULL.
* Will not attempt to destroy an object if the handle is NULL.
*
* @param p_str
* Address of a MYSTRING handle so that the function can free the MYSTRING
* object, and then change the passed variable to NULL.
****************************************************************************/
void mystring_destroy(MYSTRING* p_hString);
/*****************************************************************************
* Retrieves the number of characters that the current string holds.
*
* @param hString
* MYSTRING handle to the object that you want to query the size of.
*
* @return
* upon success:
* The size of the string is returned
*
* upon failure:
* -1 is returned (e.g., hString is NULL)
****************************************************************************/
int mystring_size(MYSTRING hString);
/*****************************************************************************
* Retrieves the total number of characters that the string can contain before
* it has to do an internal resize operation of its dynamic array.
*
* @param hString
* MYSTRING handle to the object that you want to query the capacity of.
*
* @return
* upon success:
* The capacity of the string is returend
*
* upon failure:
* -1 is returned (e.g., hString is NULL)
****************************************************************************/
int mystring_capacity(MYSTRING hString);
/*****************************************************************************
* Outputs the string to the given output file handle.
*
* @param hString
* MYSTRING handle to the object whose string data is to be output.
*
* @param out
* output file handle as the target for writing the string.
*
* @return
* upon success:
* MYSTRING_STATUS_SUCCESS
*
* upon failure:
* MYSTRING_STATUS_ERROR (e.g., either of the hString or out handles are
* invalid)
****************************************************************************/
MyString_Status mystring_output(MYSTRING hString, FILE* out);
/*****************************************************************************
* Concatenate a c-string to an existing MYSTRING object. The c-string is
* concatenated to the end of MYSTRING object's existing string data, which
* may require enlarging the MYSTRING object's capacity.
*
* Upon failure, the MYSTRING object must be left unaltered.
*
* @param hString
* The MYSTRING handle which is the destination of the concatenation
*
* @param c_string_Source
* The c-string which is the source of the concatenation
*
* @return
* upon success:
* MYSTRING_STATUS_SUCCESS
*
* upon failure:
* MYSTRING_STATUS_ERROR (e.g., either of the hString or out handles are
* invalid)
****************************************************************************/
MyString_Status mystring_concatenate_c_string(MYSTRING hString,
char * c_string);
/*****************************************************************************
* Concatenate a source MYSTRING object to an existing, destination MYSTRING
* object. The source object's string data is concatenated to the end of the
* destination object's string data, which may require enlarging the
* destination object's capacity. The source object is not altered.
*
* Upon failure, the destination object must be left unaltered.
*
* @param hStringDest
* The MYSTRING handle which is the destination of the concatenation
*
* @param hStringSource
* The MYSTRING handle which is the source of the concatenation
*
* @return
* upon success:
* MYSTRING_STATUS_SUCCESS
*
* upon failure:
* MYSTRING_STATUS_ERROR (e.g., either of the hString handle or c_string
* pointer is null)
****************************************************************************/
MyString_Status mystring_concatenate_mystring(MYSTRING hStringDest,
MYSTRING hStringSource);
/*****************************************************************************
* Truncate a string object to a given length. No change is made if the
* specified new length is greater than the object's current length.
*
* @param hString
* MYSTRING handle of the object whose string data is to be truncated
*
* @param newMaxLen
* new length of the string (if greater than the current length)
*
* @return
* upon success:
* MYSTRING_STATUS_SUCCESS
*
* upon failure:
* MYSTRING_STATUS_ERROR (e.g., the hString handle is invalid)
****************************************************************************/
MyString_Status mystring_truncate(MYSTRING hString, int newMaxLen);
/**
* Append one character to the end of the string, simulating a stack push
* operation.
*
* @param hString
* MYSTRING handle of the object whose string data is being manipulated
*
* @param ch
* The character to be appended to the string object
*
* @return
* upon success:
* MYSTRING_STATUS_SUCCESS
*
* upon failure:
* MYSTRING_STATUS_ERROR (e.g., the hString handle is invalid)
*/
MyString_Status mystring_push(MYSTRING hString, char ch);
/**
* Remove one character from the end of the string, simulating a stack pop
* operation.
*
* @param hString
* MYSTRING handle of the object whose string data is being manipulated
*
* @return
* If the string object has size at least one, the last character is removed
* from the end of the string (i.e, the string is truncated to one less than
* its previous size), and the removed character is returned.
*
* If the string object has size 0, a null character ('\0') is returned.
*/
char mystring_pop(MYSTRING hString);
/**
* Obtain the character that is at the end of the string.
*
* @param hString
* MYSTRING handle of the object whose string data is being manipulated
*
* @return
* If the string object has size at least one, the last character of the
* string is returned.
*
* If the string object has size 0, a null character ('\0') is returned.
*
* In either case, the string object is not modified in any way.
*/
char mystring_peek(MYSTRING hString);
/**
* Get a character from a given position in the string
*
* @param hString
* MYSTRING handle of the object whose string data is being manipulated
*
* @param index
* Index of the character to be retrieved
*
* @return
* If the string object has size at least one greater than the requested
* index (i.e., the requested index exists in the string), the character at
* that position is returned.
*
* If the requested index does not exist in the string, a null character
* ('\0') is returned.
*/
char mystring_get(MYSTRING hString, int index);
/**
* Put a character at a given index in the string. A character may only be
* placed at an index where a character currently exists. This function may
* not be used to increase the size of the string.
*
* @param hString
* MYSTRING handle of the object whose string data is being manipulated
*
* @param index
* Index where the character should be placed
*
* @param ch
* The character to be put at the specified index
*
* @return
* upon success:
* MYSTRING_STATUS_SUCCESS
*
* upon failure:
* MYSTRING_STATUS_ERROR (index out of bounds)
*
*
*/
MyString_Status mystring_put(MYSTRING hString, int index, char ch);
/**
* Create a new MYSTRING opaque object from a substring of an existing, source
* MYSTRING opaque object. The source object's string data, beginning at the
* specified index and extending for the specified length, is used as the new
* object's string data. The new object's size and capacity are set to exactly
* the number of characters copied from the source object to the new
* object. It is an error if the specified index is out of bounds, or if the
* number of characters specified by length, beyond the index, is out of
* bounds.
*
* @param hStringSource
* The MYSTRING handle which contains the substring to be copied to this new
* object.
*
* @param index
* The index, within the source object, of the beginning of the string data
* with which to initialize this new object.
*
* @param length
* The number of characters, beginning at index, to be copied from the
* source object, with which to initialize this new object.
*
* @return
* upon failure: NULL
* The function fails if memory to complete the operation is not
* available, or if the index is out of bounds within the source object,
* or if the length is less than one or greater than the number of
* characters available in the source object beyond the specified index.
*
* upon success:
* A MYSTRING handle that has size and capacity set to the specified
* length, and string data copied from the source object.
*/
MYSTRING mystring_init_substring(MYSTRING hStringSource, int index, int length);
/**
* Convert a string in a MYSTRING object to a c_string
*
* @param hString
* The MYSTRING handle of the string containing the data to be converted to
* a c_string
*
* @param c_string_arr
* The address of a statically- or dynamically-allocated character array
* into which the c_string will be placed.
*
* @param arrSize
* The maximum number of characters that can be copied to c_string_arr. The
* array will ALWAYS be null-terminated, even if that means that less than
* the entire string data from the MYSTRING object can be copied given this
* size.
*
* @return
* upon failure:
* NULL, e.g., hString or c_string_arr is null; arrSize is less than one
*
* upon success:
* The address of the beginning of the c_string_arr is returned, allowing
* this function to be used as an expression value, e.g., to pass to
* printf.
*/
char * mystring_to_c_string(MYSTRING hString, char c_string_arr[], int arrSize);
/**
* Read input from a given file, until being told to stop reading characters,
* or until EOF.
*
* IMPORTANT:
* The input replaces, entirely, any data that was already in the MYSTRING
* object.
*
* @param hString
* The MYSTRING handle of the string into which the input data should be
* placed, replacing any prior data in this string
*
* @param hFile
* A FILE* handle from which input should be read
*
* @param bIgnoreLeadingWhiteSpace
* If true, ignore any leading white space. Leading white space means any
* spaces, horizontal or vertical tabs, and newlines that occur before any
* non-whitespace character has been encountered. The function pointed to be
* fTerminate is not called for leading white space, when this argument is
* true, but is called when this argument is false.
*
* @param fTerminate
* A pointer to a function to be called upon reading each character, to
* determine whether the character just read is a "terminator", i.e.,
* whether mystring_input should return after storing (or not storing, as
* indicated by *pbDiscardChar) this character. This function will be called
* as each character is read. It must return TRUE (non-zero) if the
* just-read character should terminate input. It should set
* *pbDiscardChar, as described below, before returning.
*
* The fTerminate function's signature is:
* int (* fTerminate)(char ch, int * pbDiscardChar);
*
* with the following documentation:
* @param ch
* The character that was just read. fTerminate should determine whether
* this character is a terminator.
*
* @param pbDiscardChar
* Whether this character should be added to the MYSTRING object. Prior
* to returning TRUE (non-zero) or FALSE (zero), fTerminate should set
* *pbDiscardChar to one of the following values:
*
* 0: Do not discard the character. Add it to the MYSTRING object
* 1: Discard the character. Do not add it to the MYSTRING object
*
* @return
* TRUE if this character should cause termination of input; FALSE
* otherwise.
*
* The fTerminate function is not called upon EOF.
*
* @return
* upon failure:
* MYSTRING_STATUS_ERROR (any of the arguments are null)
*
* upon success:
* MYSTRING_STATUS_SUCCESS
*
* @example 1 (fairly simple)
* Let's say that you want to accept all "words", i.e., sequences of
* characters separated by white space. The white space character should be
* discarded. You could write a simple termination function to accept
* characters other than white space, discard white space, and terminate
* upon reaching any white space. The function must meet the signature
* requirements of fTerminate:
*
* int acceptNonWhite(char ch, int * pbDiscardChar)
* {
* // If the character is white space...
* if (isspace(ch))
* {
* // ... then we want it to be discarded, ...
* *pbDiscardChar = TRUE;
*
* // ... and we want to terminate input to this MYSTRING object
* return TRUE;
* }
*
* // In any other case (non-white), do not discard the character, ...
* *pbDiscardChar = FALSE;
*
* // ... and do not terminate input
* return FALSE;
* }
*
* // Now we can call mystring_input using that function:
* ...
* status = mystring_input(hString, stdin, acceptNonWhite);
* ...
*
* @example 2 (more sophisticated)
* Assume that you want to accept all sequences of digits, ignoring any even
* digit. Any other character is to terminate input and that chraracter is
* to be ignored. In this scenario, if the input were "12345 23476abc" then
* you want the MYSTRING object to contain "135", and the next time this
* function was called with the same arguments, it would retrieve "37". On
* the first call, the space is discarded. ON the second call, the 'a' is
* discarded. You might define a function such as acceptOddDigits, that
* meets the signature requirements of fTerminate:
*
* int acceptOddDigits(char ch, int * pbDiscardChar)
* {
* // If the character is a digit, ...
* if (isdigit(ch))
* {
* // First, convert the character containing the digit to its numeric
* // value.
* ch -= '0';
*
* // Discard the character if it is even; do not discard it otherwise.
* *pbDiscardChar = (ch % 2 == 0);
*
* // Do not terminate. We want to keep retrieving input.
* return FALSE;
* }
*
* // It's not a digit. Throw away the character, ...
* *pbDiscardChar = TRUE;
*
* // and terminate input into this MYSTRING object
* return TRUE;
* }
*
* // Now we can call mystring_input using that function:
* ...
* status = mystring_input(hString, stdin, acceptOddDigits);
* ...
*/
MyString_Status mystring_input(MYSTRING hString,
FILE * hFile,
int bIgnoreLeadingWhiteSpace,
int (* fTerminate)(char ch,
int * pbDiscardChar));
int lessthan(MYSTRING left, MYSTRING right);
int greaterthan(MYSTRING left, MYSTRING right);
int mystring_contains_at_all(MYSTRING hString,char c);
#endif /* MYSTRING */