Using the charstring class
- Introduction
- Manipulating Character Strings
- Comparing Character Strings
- Finding Data in Character Strings
- Transforming Character Strings
- Parsing Character Strings
- Converting Numbers and Amounts
- Encoding Character Strings
Introduction
The charstring class provides static methods for manipulating C-style character strings.
In addition to some unique methods, analogs for the standard C string functions are provided. However, unlike the standard C string functions, the charstring methods are NULL safe. Your application will not crash if a NULL is passed in, and instead, will give intuitive results.
Manipulating Character Strings
The charstring class provides methods for zeroing, duplicating, appending, copying data to, printing formatted data to, and determining the lengths of character strings.
#include <rudiments/charstring.h> #include <rudiments/stdio.h> int main(int argc, const char **argv) { char buffer[32]; // zero the buffer charstring::zero(buffer,sizeof(buffer)); // append strings, integers and floats charstring::append(buffer,"Hello "); charstring::append(buffer,"there!",6); charstring::append(buffer," "); charstring::append(buffer,(uint64_t)1); charstring::append(buffer,(uint64_t)2); charstring::append(buffer,(uint64_t)3); charstring::append(buffer," "); charstring::append(buffer,1.234,4,3); stdoutput.printf("buffer: %s\n",buffer); stdoutput.write('\n'); // get length stdoutput.printf("length(buffer)=%d\n",charstring::getLength(buffer)); stdoutput.write('\n'); // zero the buffer again charstring::zero(buffer,sizeof(buffer)); // copy to the beginning of the buffer charstring::copy(buffer,"Hello!"); stdoutput.printf("buffer: %s\n",buffer); // copy the specified number of bytes to the beginning of the buffer charstring::copy(buffer,"Hello again!",6); stdoutput.printf("buffer: %s\n",buffer); // copy to the specified offset charstring::copy(buffer,6,"again!"); stdoutput.printf("buffer: %s\n",buffer); // copy the specified number of bytes to the specified offset charstring::copy(buffer,12," Hi! blah blah blah",4); stdoutput.printf("buffer: %s\n",buffer); stdoutput.write('\n'); // get length stdoutput.printf("length(buffer)=%d\n",charstring::getLength(buffer)); stdoutput.write('\n'); // zero the buffer again charstring::zero(buffer,sizeof(buffer)); // safely copy a long string to a smaller buffer charstring::safeCopy(buffer,sizeof(buffer), "This string is longer than the buffer"); stdoutput.printf("buffer: %.*s\n",sizeof(buffer),buffer); // safely copy the specified number of bytes of a // long string to a smaller buffer charstring::safeCopy(buffer,sizeof(buffer), "This string is longer than the buffer",36); stdoutput.printf("buffer: %.*s\n",sizeof(buffer),buffer); stdoutput.write('\n'); // get length stdoutput.printf("length(buffer)=%d\n",charstring::getLength(buffer)); stdoutput.write('\n'); // zero the buffer again charstring::zero(buffer,sizeof(buffer)); // print formatted data to the buffer charstring::printf(buffer,sizeof(buffer),"%s, %05d, %7.4f", "hello",100,123.4567); stdoutput.printf("buffer: %s\n",buffer); stdoutput.write('\n'); // get length stdoutput.printf("length(buffer)=%d\n",charstring::getLength(buffer)); stdoutput.write('\n'); // duplicate a string char *completedup=charstring::duplicate("Hello there!"); char *partialdup=charstring::duplicate("Hello there!",5); stdoutput.printf("complete duplicate of \"Hello there!\": \"%s\"\n", completedup); stdoutput.printf(" partial duplicate of \"Hello there!\": \"%s\"\n", partialdup); delete[] completedup; delete[] partialdup; }
Comparing Character Strings
The charstring class also provides methods for performing various character string comparisons.
#include <rudiments/charstring.h> #include <rudiments/stdio.h> int main(int argc, const char **argv) { // comparing string... const char * const strings[]={ "hello","HELLO","hello there","HELLO THERE",NULL }; stdoutput.write("direct comparison...\n"); for (const char * const *s=strings; *s; s++) { stdoutput.printf(" does \"hello\"=\"%s\" %s?\n",*s, (!charstring::compare("hello",*s))?"yes":"no"); } stdoutput.write('\n'); stdoutput.write("only first 5 bytes...\n"); for (const char * const *s=strings; *s; s++) { stdoutput.printf(" does \"hello\"=\"%s\"? %s\n",*s, (!charstring::compare("hello",*s,5))?"yes":"no"); } stdoutput.write('\n'); stdoutput.write("ignoring case...\n"); for (const char * const *s=strings; *s; s++) { stdoutput.printf(" does \"hello\"=\"%s\"? %s\n",*s, (!charstring::compareIgnoringCase("hello",*s,5))? "yes":"no"); } stdoutput.write('\n'); stdoutput.write("ignoring case, only first 5 bytes...\n"); for (const char * const *s=strings; *s; s++) { stdoutput.printf(" does \"hello\"=\"%s\"? %s\n",*s, (!charstring::compareIgnoringCase("hello",*s,5))? "yes":"no"); } stdoutput.write('\n'); // member of a set... const char * const greetings[]={ "hello","hi","good morning",NULL }; const char * const lowercaseexpressions[]={ "hello","hi","bye","goodbye",NULL }; const char * const uppercaseexpressions[]={ "HELLO","HI","BYE","GOODBYE",NULL }; stdoutput.write("considering case...\n"); for (const char * const *le=lowercaseexpressions; *le; le++) { stdoutput.printf(" is \"%s\" a greeting? %s\n",*le, (charstring::isInSet(*le,greetings))?"yes":"no"); } stdoutput.write('\n'); stdoutput.write("ignoring case...\n"); for (const char * const *ue=uppercaseexpressions; *ue; ue++) { stdoutput.printf(" is \"%s\" a greeting? %s\n",*ue, (charstring::isInSetIgnoringCase(*ue,greetings))? "yes":"no"); } stdoutput.write('\n'); // does one string contain another? const char phrase[]="the quick brown fox jumped over the lazy dog"; const char * const lowercasewords[]={ "quick","brown","fox","lazy","dog","hello","goodbye",NULL }; const char * const uppercasewords[]={ "QUICK","BROWN","FOX","LAZY","DOG","HELLO","GOODBYE",NULL }; stdoutput.write("considering case...\n"); for (const char * const *lw=lowercasewords; *lw; lw++) { stdoutput.printf(" does \"%s\" contain \"%s\"? %s\n", phrase,*lw, (charstring::contains(phrase,*lw))?"yes":"no"); } stdoutput.write('\n'); stdoutput.write("ignoring case...\n"); for (const char * const *uw=uppercasewords; *uw; uw++) { stdoutput.printf(" does \"%s\" contain \"%s\"? %s\n", phrase,*uw, (charstring::contains(phrase,*uw))?"yes":"no"); } stdoutput.write('\n'); }
Finding Data in Character Strings
The charstring class also provides methods for finding characters or other character strings within character strings.
The findFirst()/findFirstOfSet() and findLast() methods return the first/last instance of a character/string/set within a string, or NULL if no match is found.
#include <rudiments/charstring.h> #include <rudiments/stdio.h> int main(int argc, const char **argv) { // first/last instances of a character or string... const char phrase[]="1 and 2 and 3 and 4"; const char numbers[]="1234"; const char *firsta=charstring::findFirst(phrase,'a'); const char *firstand=charstring::findFirst(phrase,"and"); const char *lasta=charstring::findLast(phrase,'a'); const char *lastand=charstring::findLast(phrase,"and"); const char *firstnum=charstring::findFirstOfSet(phrase,numbers); stdoutput.printf("in the phrase: \"%s\"...\n",phrase); stdoutput.printf(" the first 'a' is : \"%s\"\n",firsta); stdoutput.printf(" the first \"and\" is : \"%s\"\n",firstand); stdoutput.printf(" the last 'a' is : \"%s\"\n",lasta); stdoutput.printf(" the last \"and\" is : \"%s\"\n",lastand); stdoutput.printf(" the first number is : \"%s\"\n",firstnum); stdoutput.write('\n'); }
Transforming Character Strings
The charstring class also provides methods for transforming character strings.
#include <rudiments/charstring.h> #include <rudiments/stdio.h> int main(int argc, const char **argv) { char hellothere[]=" hello there! "; // upper-case... charstring::upper(hellothere); stdoutput.printf("upper cased: \"%s\"\n",hellothere); // lower-case... charstring::lower(hellothere); stdoutput.printf("lower cased: \"%s\"\n",hellothere); // capitalized... charstring::capitalize(hellothere); stdoutput.printf("capitalized: \"%s\"\n",hellothere); // right trimmed... charstring::rightTrim(hellothere); stdoutput.printf("right trimmed: \"%s\"\n",hellothere); // left trimmed... charstring::leftTrim(hellothere); stdoutput.printf("left trimmed: \"%s\"\n",hellothere); stdoutput.write('\n'); char paragraph[]="Hello there.\n This is a paragraph\n " "with random\n carriage returns\n " "scattered throughout."; // original... stdoutput.printf("original text:\n%s\n\n",paragraph); // stripped of carraige returns... charstring::strip(paragraph,'\n'); stdoutput.printf("text without carriage returns:\n%s\n\n",paragraph); // stripped of "Hello there."... charstring::strip(paragraph,"Hello there. "); stdoutput.printf("text without \"Hello There. \":\n%s\n\n",paragraph); // with replacements... charstring::replace(paragraph,' ','_'); stdoutput.printf("text with spaces replaced by underscores:\n%s\n\n", paragraph); char paddedtext[]=" hello "; // original... stdoutput.printf("original text: \"%s\"\n",paddedtext); // left-justified... charstring::leftJustify(paddedtext,charstring::getLength(paddedtext)); stdoutput.printf("left-justified: \"%s\"\n",paddedtext); // right-justified... charstring::rightJustify(paddedtext,charstring::getLength(paddedtext)); stdoutput.printf("right-justified: \"%s\"\n",paddedtext); // centered... charstring::center(paddedtext,charstring::getLength(paddedtext)); stdoutput.printf("centered: \"%s\"\n",paddedtext); stdoutput.write('\n'); const char unpaddedtext[]="hellothere"; // original... stdoutput.printf("original text: \"%s\"\n",unpaddedtext); // left-padded char *leftpadded=charstring::pad(unpaddedtext,' ',-1,15); stdoutput.printf("left padded text: \"%s\"\n",leftpadded); delete[] leftpadded; // right-padded char *rightpadded=charstring::pad(unpaddedtext,' ',1,15); stdoutput.printf("right padded text: \"%s\"\n",rightpadded); delete[] rightpadded; // center-padded char *centerpadded=charstring::pad(unpaddedtext,' ',0,15); stdoutput.printf("center padded text: \"%s\"\n",centerpadded); delete[] centerpadded; }
Parsing Character Strings
The charstring class also provides methods for splitting character strings, finding substrings and inserting text into a character string.
#include <rudiments/charstring.h> #include <rudiments/stdio.h> int main(int argc, const char **argv) { const char str[]="All along the untrodden paths of the future..."; // split... char **parts; uint64_t partcount; charstring::split(str," ",true,&parts,&partcount); stdoutput.printf("original string:\n %s\n",str); stdoutput.printf("split on space:\n"); for (uint64_t i=0; i<partcount; i++) { stdoutput.printf(" %s\n",parts[i]); } stdoutput.write('\n'); for (uint64_t i=0; i<partcount; i++) { delete[] parts[i]; } delete[] parts; // substring... char *substring1=charstring::getSubString(str,14); char *substring2=charstring::getSubString(str,14,28); stdoutput.printf("string starting at index 14: %s\n",substring1); stdoutput.printf("string from index 14 to 21 : %s\n",substring2); stdoutput.write('\n'); delete[] substring1; delete[] substring2; // insert string... char *newstr=charstring::insertString(str, ", I can see the footprints of an unseen hand",43); stdoutput.printf("string after insert:\n %s\n",newstr); stdoutput.write('\n'); delete[] newstr; }
Converting Numbers and Amounts
The charstring class also provides methods for converting numbers and dollar amounts to and from character strings.
#include <rudiments/charstring.h> #include <rudiments/stdio.h> int main(int argc, const char **argv) { // conversion of numbers to strings... char *intstr=charstring::parseNumber((uint64_t)12345); char *floatstr=charstring::parseNumber((float)12.345,5,3); stdoutput.printf("numbers as strings: %s, %s\n",intstr,floatstr); stdoutput.write('\n'); delete[] intstr; delete[] floatstr; // conversion of strings to numbers... int64_t intnum=charstring::convertToInteger("12345"); uint64_t uintnum=charstring::convertToUnsignedInteger("12345"); long double floatnum=charstring::convertToFloat("12.345"); stdoutput.printf("strings as numbers: %lld, %lld, %5.3Lf\n", intnum,uintnum,floatnum); stdoutput.write('\n'); // identification of numeric strings... const char * const numbers[]={ "1","-1","1.1","-1.1","one","hello",NULL }; for (const char * const *n=numbers; *n; n++) { stdoutput.printf("%s %s a number\n",*n, (charstring::isNumber(*n))?"is":"is not"); stdoutput.printf("%s %s an integer\n",*n, (charstring::isInteger(*n))?"is":"is not"); } stdoutput.write('\n'); // integer lengths uint64_t integers[]={ 1,23,456,7890,12345,678901,0 }; for (uint64_t *i=integers; *i; i++) { stdoutput.printf("it would take %d bytes to store " "%lld as a string\n", charstring::getIntegerLength(*i),*i); } stdoutput.write('\n'); // dollar amounts const char dollarstr[]="$123.45"; int64_t pennies=charstring::convertAmount(dollarstr); char *dollars=charstring::convertAmount(pennies); stdoutput.printf("%s as pennies: %lld\n",dollarstr,pennies); stdoutput.printf("%lld pennies as dollars: %s\n",pennies,dollars); }
Encoding Character Strings
The charstring class also provides methods for escaping, encoding and obfuscating character strings.
#include <rudiments/charstring.h> #include <rudiments/stdio.h> int main(int argc, const char **argv) { // backslash-escaping of quote, backslash and space characters... const char path[]="\"C:\\Program Files\\Firstworks\""; stdoutput.printf("original path:\n %s\n",path); char *escapedpath=charstring::escape(path,"\"\\ "); stdoutput.printf("escaped path:\n %s\n",escapedpath); char *unescapedpath=charstring::unescape(escapedpath); stdoutput.printf("unescaped path:\n %s\n",unescapedpath); stdoutput.write('\n'); delete[] escapedpath; delete[] unescapedpath; // url encoding... const char urlstr[]="string with spaces and symbols: \\{}\"\'"; stdoutput.printf("original string:\n %s\n",urlstr); char *encodedstr=charstring::urlEncode(urlstr); stdoutput.printf("url encoded string:\n %s\n",encodedstr); char *unencodedstr=charstring::urlDecode(encodedstr); stdoutput.printf("url unencoded string:\n %s\n",unencodedstr); stdoutput.write('\n'); delete[] encodedstr; delete[] unencodedstr; // base-64 encoding... const byte_t text[]="All along the untrodden " "paths of the future..."; stdoutput.printf("original text:\n %s\n",text); char *encodedtext=charstring::base64Encode(text); stdoutput.printf("encoded text:\n %s\n",encodedtext); byte_t *decodedtext=charstring::base64Decode(encodedtext); stdoutput.printf("decoded text:\n %s\n",decodedtext); stdoutput.write('\n'); delete[] encodedtext; delete[] decodedtext; // obfuscation... char data[]="sensitive data"; stdoutput.printf("original data:\n %s\n",data); charstring::obfuscate(data); stdoutput.write("obfuscated data:\n "); stdoutput.safePrint(data); stdoutput.write("\n"); charstring::deobfuscate(data); stdoutput.printf("deobfuscated data:\n %s\n",data); }