a firstworks project
Rudiments
About Documentation Download Licensing News

Using the wcharstring class


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;
}
Copyright 2017 - David Muse - Contact