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.
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::length(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::length(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::length(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::length(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;
}
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::inSet(*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::inSetIgnoringCase(*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');
}
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');
}
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::length(paddedtext));
stdoutput.printf("left-justified: \"%s\"\n",paddedtext);
// right-justified...
charstring::rightJustify(paddedtext,charstring::length(paddedtext));
stdoutput.printf("right-justified: \"%s\"\n",paddedtext);
// centered...
charstring::center(paddedtext,charstring::length(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;
}
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::subString(str,14);
char *substring2=charstring::subString(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;
}
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::toInteger("12345");
uint64_t uintnum=charstring::toUnsignedInteger("12345");
long double floatnum=charstring::toFloat("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::integerLength(*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);
}
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) {
// http escape...
const char httpstr[]="string with spaces and symbols: \\{}\"\'";
stdoutput.printf("original string:\n %s\n",httpstr);
char *escapedstr=charstring::httpEscape(httpstr);
stdoutput.printf("http escaped string:\n %s\n",escapedstr);
char *unescapedstr=charstring::httpUnescape(escapedstr);
stdoutput.printf("http unescaped string:\n %s\n",unescapedstr);
stdoutput.write('\n');
delete[] escapedstr;
delete[] unescapedstr;
// 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;
// base-64 encoding...
const unsigned char 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);
unsigned char *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);
}