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