Overview¶
Background¶
The enhanced string library provides additional features built on top of C standard library strings.
Features¶
Additional string functions, such as substr, replace, trim and case insensitive compare.
String stream, for building up long strings piece by piece.
Regular expression substring extraction.
Examples¶
Copy To¶
#include <c-craft/str.h>
MEM_SCOPE mem = sm_create(0);
char* from = "string with space";
char *to = str_copyto_w(mem, from, ' '); /* to contains 'string' */
sm_free(to);
Trim¶
#include <c-craft/str.h>
MEM_SCOPE mem = sm_create(0);
char *str = " \t\n\r\f a string to trim. \r\n\t ";
char *buf = str_trim(mem, str); /* buf contains 'a string to trim.' */
sm_free(to);
Casing¶
#include <c-craft/str.h>
MEM_SCOPE mem = sm_create(0);
char *lower = str_lower(mem, "SHOUTING !"; /* lower is 'shouting !' */
char *upper = str_upper(mem, "Shush !"; /* upper is 'SHUSH !' */
Case Insensitive Compare¶
#include <c-craft/str.h>
if(str_icmp("Martin", "martin") == 0)
printf("This will happen");
Find Substring (contains)¶
#include <c-craft/str.h>
text = "My old man's a dustman";
int i = str_contains_s(text, "man"); /* i is TRUE */
int i = str_contains_s(text, "woman"); /* i is FALSE */
You may use regular expressions with regex versions of these functions. However, this library will interpret the ‘^’ and ‘$’ pattern characters to match start and end of buffer, rather than start and end of line. If the text you are applying the regex to contains newlines that you want to match you must use ‘n’ in your pattern.
Starts With, Ends With¶
#include <c-craft/str.h>
text = "My old man's a dustman";
int i = str_starts_with_s(text, "My"); /* i is TRUE */
int i = str_ends_with_w(text, "man"); /* i is FALSE */
Replace¶
#include <c-craft/str.h>
MEM_SCOPE mem = sm_create(0);
char *text = "The deep blue sea";
char *cp = str_replace_c(mem, text, 'e', 'o'); /* cp is 'Tho doop bluo soa' */
sm_free(to);
String Stream¶
The string stream module allows to write to a string as though it was a file. For example:
#include <c-craft/str.h>
MEM_SCOPE mem = sm_create(0);
SSTREAM s = str_screate(mem);
str_sprintf(s, "Hello %s, you weigh %dlbs.\n", "Frederic", 152);
str_sprintf(s, "You are %d years old.\n", 42);
char *result = str_sclose(s); /* Closes all OS resources */
sm_free(mem);
Note that ‘result’ now contains the streamed text as a string. After the ‘str_sclose’ call the memory is owned by the ‘mem’ scope provided in the str_screate() call. As with all scoped memory it must be released when done. Additionally, if a STR_STREAM is created it must be closed with ‘str_sclose’. Failure to do so will lead to a memory leak. For more information about memory scopes, see the MEM package.
Extraction¶
The extraction module provides the ability to extract substrings based on chained regular expressions.
A chained regular expression is an array of expressions applied to a piece of text that each operates on the result of the previous expression. The use case for this is where text may be identified contextually. For example, consider this text.
‘I want to get (this text) but not this’
‘(this text)’ may be extracted using ‘\([A-Za-z ]+\)’. However the real requirement is to remove the surrounding brackets. To do that we would use ‘[A-Za-z ]+’ on the result. Thus a chained regular expression to do the whole thing in one go would be ‘\([A-Za-z ]+\)\n[A-Za-z ]+’. NOTE the ‘\n’ separator, that divides the expressions in the chain.
Additionally, the ‘!’ not operator as the first character of a regular expression will pass all text that does not match the remainder of the regular expression to the next expression in the chain.
Conversions¶
The enhanced string library provides conversion functions to and from string for most of the basic types. To convert to string use:
#include <c-craft/str.h>
MEM_SCOPE mem = sm_create(0);
char *str = str_from_long(NULL, 9876543210L);
sm_free(str);
Note that the first parameter is a memory scope, so may be a scope of your choosing.
To convert from string use:
#include <c-craft/str.h>
double d = str_to_double("2.56789e-4", NULL);
If the value cannot be parsed, because it is not valid, then a 0 is returned. If you prefer to handle errors differently the second parameter may be a pointer to an int. If the operation fails it will be set to FALSE.
#include <c-craft/str.h>
int ok = TRUE;
float f = str_to_float("bad", &ok);
/* ok is now FALSE, and f is 0.0 */
