a firstworks project
Rudiments
About Documentation Download Licensing News

Using the ucs2charstring class


Introduction

The ucs2charstring class provides static methods for manipulating C-style UCS-2 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 ucs2charstring methods are NULL safe. Your application will not crash if a NULL is passed in, and instead, will give intuitive results.

Manipulating UCS-2 Character Strings

The ucs2charstring class provides methods for zeroing, duplicating, appending, copying data to, printing formatted data to, and determining the lengths of UCS-2 character strings.

#include <rudiments/ucs2charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	ucs2_t		buffer[32];


	// zero the buffer
	ucs2charstring::zero(buffer,32);


	// append strings, integers and floats
	ucs2literal(hello,"Hello ");
	ucs2literal(there,"there!");
	ucs2literal(space," ");
	ucs2charstring::append(buffer,hello);
	ucs2charstring::append(buffer,there,6);
	ucs2charstring::append(buffer,space);
	ucs2charstring::append(buffer,(uint64_t)1);
	ucs2charstring::append(buffer,(uint64_t)2);
	ucs2charstring::append(buffer,(uint64_t)3);
	ucs2charstring::append(buffer,space);
	ucs2charstring::append(buffer,1.234,4,3);

	char	*bufstr=charstring::duplicateUcs2(buffer);
	stdoutput.printf("buffer: %s\n",bufstr);
	delete[] bufstr;
	stdoutput.write('\n');


	// get length
	stdoutput.printf("length(buffer)=%d\n",
			ucs2charstring::getLength(buffer));
	stdoutput.write('\n');


	// zero the buffer again
	ucs2charstring::zero(buffer,32);


	// copy to the beginning of the buffer
	ucs2literal(hello2,"Hello!");
	ucs2charstring::copy(buffer,hello2);
	bufstr=charstring::duplicateUcs2(buffer);
	stdoutput.printf("buffer: %s\n",bufstr);
	delete[] bufstr;


	// copy the specified number of characters to the beginning
	ucs2literal(helloagain,"Hello again!");
	ucs2charstring::copy(buffer,helloagain,6);
	bufstr=charstring::duplicateUcs2(buffer);
	stdoutput.printf("buffer: %s\n",bufstr);
	delete[] bufstr;


	// copy to the specified offset
	ucs2literal(again,"again!");
	ucs2charstring::copy(buffer,6,again);
	bufstr=charstring::duplicateUcs2(buffer);
	stdoutput.printf("buffer: %s\n",bufstr);
	delete[] bufstr;


	// copy the specified number of characters to the specified offset
	ucs2literal(hiblah," Hi!  blah blah blah");
	ucs2charstring::copy(buffer,12,hiblah,4);
	bufstr=charstring::duplicateUcs2(buffer);
	stdoutput.printf("buffer: %s\n",bufstr);
	delete[] bufstr;
	stdoutput.write('\n');


	// get length
	stdoutput.printf("length(buffer)=%d\n",
			ucs2charstring::getLength(buffer));
	stdoutput.write('\n');


	// zero the buffer again
	ucs2charstring::zero(buffer,32);


	// safely copy a long string to a smaller buffer
	ucs2literal(longstr,"This string is longer than the buffer");
	ucs2charstring::safeCopy(buffer,32,longstr);
	bufstr=charstring::duplicateUcs2(buffer);
	stdoutput.printf("buffer: %s\n",bufstr);
	delete[] bufstr;


	// safely copy the specified number of characters
	ucs2charstring::safeCopy(buffer,32,longstr,36);
	bufstr=charstring::duplicateUcs2(buffer);
	stdoutput.printf("buffer: %s\n",bufstr);
	delete[] bufstr;
	stdoutput.write('\n');


	// get length
	stdoutput.printf("length(buffer)=%d\n",
			ucs2charstring::getLength(buffer));
	stdoutput.write('\n');


	// duplicate a string
	ucs2literal(hellothere,"Hello there!");
	ucs2_t	*completedup=ucs2charstring::duplicate(hellothere);
	ucs2_t	*partialdup=ucs2charstring::duplicate(hellothere,5);

	char	*cdstr=charstring::duplicateUcs2(completedup);
	char	*pdstr=charstring::duplicateUcs2(partialdup);
	stdoutput.printf("complete duplicate of \"Hello there!\": \"%s\"\n",
							cdstr);
	stdoutput.printf(" partial duplicate of \"Hello there!\": \"%s\"\n",
							pdstr);
	delete[] cdstr;
	delete[] pdstr;
	delete[] completedup;
	delete[] partialdup;
}

Comparing UCS-2 Character Strings

The ucs2charstring class also provides methods for performing various UCS-2 character string comparisons.

#include <rudiments/ucs2charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	// comparing strings...
	ucs2literal(uhello,"hello");
	ucs2literal(uHELLO,"HELLO");
	ucs2literal(uhellothere,"hello there");
	ucs2literal(uHELLOTHERE,"HELLO THERE");

	const ucs2_t * const strings[]={
		uhello,uHELLO,uhellothere,uHELLOTHERE,NULL
	};

	stdoutput.write("direct comparison...\n");
	for (const ucs2_t * const *s=strings; *s; s++) {
		char	*sstr=charstring::duplicateUcs2(*s);
		stdoutput.printf("  does \"hello\"=\"%s\"  %s?\n",sstr,
			(!ucs2charstring::compare(uhello,*s))?"yes":"no");
		delete[] sstr;
	}
	stdoutput.write('\n');

	stdoutput.write("only first 5 characters...\n");
	for (const ucs2_t * const *s=strings; *s; s++) {
		char	*sstr=charstring::duplicateUcs2(*s);
		stdoutput.printf("  does \"hello\"=\"%s\"?  %s\n",sstr,
			(!ucs2charstring::compare(uhello,*s,5))?"yes":"no");
		delete[] sstr;
	}
	stdoutput.write('\n');

	stdoutput.write("ignoring case...\n");
	for (const ucs2_t * const *s=strings; *s; s++) {
		char	*sstr=charstring::duplicateUcs2(*s);
		stdoutput.printf("  does \"hello\"=\"%s\"?  %s\n",sstr,
			(!ucs2charstring::compareIgnoringCase(uhello,*s))?
							"yes":"no");
		delete[] sstr;
	}
	stdoutput.write('\n');

	stdoutput.write("ignoring case, only first 5 characters...\n");
	for (const ucs2_t * const *s=strings; *s; s++) {
		char	*sstr=charstring::duplicateUcs2(*s);
		stdoutput.printf("  does \"hello\"=\"%s\"?  %s\n",sstr,
			(!ucs2charstring::compareIgnoringCase(uhello,*s,5))?
							"yes":"no");
		delete[] sstr;
	}
	stdoutput.write('\n');



	// member of a set...
	ucs2literal(uhi,"hi");
	ucs2literal(ugoodmorning,"good morning");
	ucs2literal(ubye,"bye");
	ucs2literal(ugoodbye,"goodbye");
	ucs2literal(uBYE,"BYE");
	ucs2literal(uGOODBYE,"GOODBYE");
	ucs2literal(uHI,"HI");

	const ucs2_t * const greetings[]={
		uhello,uhi,ugoodmorning,NULL
	};
	const ucs2_t * const lowercaseexpressions[]={
		uhello,uhi,ubye,ugoodbye,NULL
	};
	const ucs2_t * const uppercaseexpressions[]={
		uHELLO,uHI,uBYE,uGOODBYE,NULL
	};

	stdoutput.write("considering case...\n");
	for (const ucs2_t * const *le=lowercaseexpressions; *le; le++) {
		char	*lestr=charstring::duplicateUcs2(*le);
		stdoutput.printf("  is \"%s\" a greeting?  %s\n",lestr,
			(ucs2charstring::isInSet(*le,greetings))?"yes":"no");
		delete[] lestr;
	}
	stdoutput.write('\n');

	stdoutput.write("ignoring case...\n");
	for (const ucs2_t * const *ue=uppercaseexpressions; *ue; ue++) {
		char	*uestr=charstring::duplicateUcs2(*ue);
		stdoutput.printf("  is \"%s\" a greeting?  %s\n",uestr,
			(ucs2charstring::isInSetIgnoringCase(*ue,greetings))?
							"yes":"no");
		delete[] uestr;
	}
	stdoutput.write('\n');


	// does one string contain another?
	ucs2literal(phrase,"the quick brown fox jumped over the lazy dog");
	ucs2literal(uquick,"quick");
	ucs2literal(ubrown,"brown");
	ucs2literal(ufox,"fox");
	ucs2literal(ulazy,"lazy");
	ucs2literal(udog,"dog");
	ucs2literal(uhello2,"hello");
	ucs2literal(ugoodbye2,"goodbye");
	ucs2literal(uQUICK,"QUICK");
	ucs2literal(uBROWN,"BROWN");
	ucs2literal(uFOX,"FOX");
	ucs2literal(uLAZY,"LAZY");
	ucs2literal(uDOG,"DOG");
	ucs2literal(uHELLO2,"HELLO");
	ucs2literal(uGOODBYE2,"GOODBYE");

	const ucs2_t * const lowercasewords[]={
		uquick,ubrown,ufox,ulazy,udog,uhello2,ugoodbye2,NULL
	};
	const ucs2_t * const uppercasewords[]={
		uQUICK,uBROWN,uFOX,uLAZY,uDOG,uHELLO2,uGOODBYE2,NULL
	};

	char	*phrasestr=charstring::duplicateUcs2(phrase);

	stdoutput.write("considering case...\n");
	for (const ucs2_t * const *lw=lowercasewords; *lw; lw++) {
		char	*lwstr=charstring::duplicateUcs2(*lw);
		stdoutput.printf("  does \"%s\" contain \"%s\"?  %s\n",
			phrasestr,lwstr,
			(ucs2charstring::contains(phrase,*lw))?"yes":"no");
		delete[] lwstr;
	}
	stdoutput.write('\n');

	stdoutput.write("ignoring case...\n");
	for (const ucs2_t * const *uw=uppercasewords; *uw; uw++) {
		char	*uwstr=charstring::duplicateUcs2(*uw);
		stdoutput.printf("  does \"%s\" contain \"%s\"?  %s\n",
			phrasestr,uwstr,
			(ucs2charstring::containsIgnoringCase(phrase,*uw))?
							"yes":"no");
		delete[] uwstr;
	}
	stdoutput.write('\n');

	delete[] phrasestr;
}

Finding Data in UCS-2 Character Strings

The ucs2charstring class also provides methods for finding characters or other UCS-2 character strings within UCS-2 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/ucs2charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	// first/last instances of a character or string...
	ucs2literal(phrase,"1 and 2 and 3 and 4");
	ucs2literal(numbers,"1234");
	ucs2literal(andstr,"and");

	const ucs2_t	*firsta=ucs2charstring::findFirst(phrase,(ucs2_t)'a');
	const ucs2_t	*firstand=ucs2charstring::findFirst(phrase,andstr);

	const ucs2_t	*lasta=ucs2charstring::findLast(phrase,(ucs2_t)'a');
	const ucs2_t	*lastand=ucs2charstring::findLast(phrase,andstr);

	const ucs2_t	*firstnum=ucs2charstring::findFirstOfSet(
							phrase,numbers);

	char	*phrasestr=charstring::duplicateUcs2(phrase);
	char	*firstastr=charstring::duplicateUcs2(firsta);
	char	*firstandstr=charstring::duplicateUcs2(firstand);
	char	*lastastr=charstring::duplicateUcs2(lasta);
	char	*lastandstr=charstring::duplicateUcs2(lastand);
	char	*firstnumstr=charstring::duplicateUcs2(firstnum);

	stdoutput.printf("in the phrase: \"%s\"...\n",phrasestr);
	stdoutput.printf("  the first 'a' is	: \"%s\"\n",firstastr);
	stdoutput.printf("  the first \"and\" is	: \"%s\"\n",firstandstr);
	stdoutput.printf("  the last 'a' is	: \"%s\"\n",lastastr);
	stdoutput.printf("  the last \"and\" is	: \"%s\"\n",lastandstr);
	stdoutput.printf("  the first number is	: \"%s\"\n",firstnumstr);
	stdoutput.write('\n');

	delete[] phrasestr;
	delete[] firstastr;
	delete[] firstandstr;
	delete[] lastastr;
	delete[] lastandstr;
	delete[] firstnumstr;
}

Transforming UCS-2 Character Strings

The ucs2charstring class also provides methods for transforming UCS-2 character strings.

#include <rudiments/ucs2charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	ucs2literal(htsrc,"   hello there!   ");
	ucs2_t	hellothere[19];
	ucs2charstring::copy(hellothere,htsrc);

	char	*str;

	// upper-case...
	ucs2charstring::upper(hellothere);
	str=charstring::duplicateUcs2(hellothere);
	stdoutput.printf("upper cased:   \"%s\"\n",str);
	delete[] str;

	// lower-case...
	ucs2charstring::lower(hellothere);
	str=charstring::duplicateUcs2(hellothere);
	stdoutput.printf("lower cased:   \"%s\"\n",str);
	delete[] str;

	// capitalized...
	ucs2charstring::capitalize(hellothere);
	str=charstring::duplicateUcs2(hellothere);
	stdoutput.printf("capitalized:   \"%s\"\n",str);
	delete[] str;

	// right trimmed...
	ucs2charstring::rightTrim(hellothere);
	str=charstring::duplicateUcs2(hellothere);
	stdoutput.printf("right trimmed: \"%s\"\n",str);
	delete[] str;

	// left trimmed...
	ucs2charstring::leftTrim(hellothere);
	str=charstring::duplicateUcs2(hellothere);
	stdoutput.printf("left trimmed:  \"%s\"\n",str);
	delete[] str;
	stdoutput.write('\n');



	ucs2literal(parasrc,
		"Hello there.\n This is a paragraph\n "
		"with random\n carriage returns\n "
		"scattered throughout.");
	ucs2_t	paragraph[100];
	ucs2charstring::copy(paragraph,parasrc);

	// original...
	str=charstring::duplicateUcs2(paragraph);
	stdoutput.printf("original text:\n%s\n\n",str);
	delete[] str;

	// stripped of carriage returns...
	ucs2charstring::strip(paragraph,(ucs2_t)'\n');
	str=charstring::duplicateUcs2(paragraph);
	stdoutput.printf("text without carriage returns:\n%s\n\n",str);
	delete[] str;

	// stripped of "Hello there."...
	ucs2literal(htstrip,"Hello there. ");
	ucs2charstring::strip(paragraph,htstrip);
	str=charstring::duplicateUcs2(paragraph);
	stdoutput.printf("text without \"Hello There. \":\n%s\n\n",str);
	delete[] str;

	// with replacements...
	ucs2charstring::replace(paragraph,(ucs2_t)' ',(ucs2_t)'_');
	str=charstring::duplicateUcs2(paragraph);
	stdoutput.printf("text with spaces replaced by underscores:\n%s\n\n",
								str);
	delete[] str;



	ucs2literal(ptsrc,"   hello   ");
	ucs2_t	paddedtext[12];
	ucs2charstring::copy(paddedtext,ptsrc);

	// original...
	str=charstring::duplicateUcs2(paddedtext);
	stdoutput.printf("original text:   \"%s\"\n",str);
	delete[] str;

	// left-justified...
	ucs2charstring::leftJustify(paddedtext,
				ucs2charstring::getLength(paddedtext));
	str=charstring::duplicateUcs2(paddedtext);
	stdoutput.printf("left-justified:  \"%s\"\n",str);
	delete[] str;

	// right-justified...
	ucs2charstring::rightJustify(paddedtext,
				ucs2charstring::getLength(paddedtext));
	str=charstring::duplicateUcs2(paddedtext);
	stdoutput.printf("right-justified: \"%s\"\n",str);
	delete[] str;

	// centered...
	ucs2charstring::center(paddedtext,
				ucs2charstring::getLength(paddedtext));
	str=charstring::duplicateUcs2(paddedtext);
	stdoutput.printf("centered:        \"%s\"\n",str);
	delete[] str;
	stdoutput.write('\n');



	ucs2literal(unpaddedtext,"hellothere");

	// original...
	str=charstring::duplicateUcs2(unpaddedtext);
	stdoutput.printf("original text:      \"%s\"\n",str);
	delete[] str;

	// left-padded
	ucs2_t	*leftpadded=ucs2charstring::pad(unpaddedtext,
						(ucs2_t)' ',-1,15);
	str=charstring::duplicateUcs2(leftpadded);
	stdoutput.printf("left padded text:   \"%s\"\n",str);
	delete[] str;
	delete[] leftpadded;

	// right-padded
	ucs2_t	*rightpadded=ucs2charstring::pad(unpaddedtext,
						(ucs2_t)' ',1,15);
	str=charstring::duplicateUcs2(rightpadded);
	stdoutput.printf("right padded text:  \"%s\"\n",str);
	delete[] str;
	delete[] rightpadded;

	// center-padded
	ucs2_t	*centerpadded=ucs2charstring::pad(unpaddedtext,
						(ucs2_t)' ',0,15);
	str=charstring::duplicateUcs2(centerpadded);
	stdoutput.printf("center padded text: \"%s\"\n",str);
	delete[] str;
	delete[] centerpadded;
}

Parsing UCS-2 Character Strings

The ucs2charstring class also provides methods for splitting UCS-2 character strings, finding substrings and inserting text into a UCS-2 character string.

#include <rudiments/ucs2charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	ucs2literal(str,"All along the untrodden paths of the future...");

	// split...
	ucs2_t		**parts;
	uint64_t	partcount;
	ucs2literal(space," ");
	ucs2charstring::split(str,space,true,&parts,&partcount);

	char	*strstr=charstring::duplicateUcs2(str);
	stdoutput.printf("original string:\n  %s\n",strstr);
	delete[] strstr;

	stdoutput.printf("split on space:\n");
	for (uint64_t i=0; i<partcount; i++) {
		char	*partstr=charstring::duplicateUcs2(parts[i]);
		stdoutput.printf("  %s\n",partstr);
		delete[] partstr;
	}
	stdoutput.write('\n');

	for (uint64_t i=0; i<partcount; i++) {
		delete[] parts[i];
	}
	delete[] parts;



	// substring...
	ucs2_t	*substring1=ucs2charstring::getSubString(str,14);
	ucs2_t	*substring2=ucs2charstring::getSubString(str,14,28);

	char	*ss1str=charstring::duplicateUcs2(substring1);
	char	*ss2str=charstring::duplicateUcs2(substring2);
	stdoutput.printf("string starting at index 14: %s\n",ss1str);
	stdoutput.printf("string from index 14 to 21 : %s\n",ss2str);
	stdoutput.write('\n');

	delete[] ss1str;
	delete[] ss2str;
	delete[] substring1;
	delete[] substring2;



	// insert string...
	ucs2literal(insertstr,", I can see the footprints of an unseen hand");
	ucs2_t	*newstr=ucs2charstring::insertString(str,insertstr,43);

	char	*newstrstr=charstring::duplicateUcs2(newstr);
	stdoutput.printf("string after insert:\n  %s\n",newstrstr);
	stdoutput.write('\n');

	delete[] newstrstr;
	delete[] newstr;
}

Converting Numbers and Amounts

The ucs2charstring class also provides methods for converting numbers and dollar amounts to and from UCS-2 character strings.

#include <rudiments/ucs2charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	// conversion of numbers to strings...
	ucs2_t	*intstr=ucs2charstring::parseNumber((uint64_t)12345);
	ucs2_t	*floatstr=ucs2charstring::parseNumber((float)12.345,5,3);

	char	*intstrstr=charstring::duplicateUcs2(intstr);
	char	*floatstrstr=charstring::duplicateUcs2(floatstr);
	stdoutput.printf("numbers as strings: %s, %s\n",intstrstr,floatstrstr);
	stdoutput.write('\n');

	delete[] intstrstr;
	delete[] floatstrstr;
	delete[] intstr;
	delete[] floatstr;



	// conversion of strings to numbers...
	ucs2literal(intlit,"12345");
	ucs2literal(floatlit,"12.345");
	int64_t		intnum=ucs2charstring::convertToInteger(intlit);
	uint64_t	uintnum=ucs2charstring::convertToUnsignedInteger(intlit);
	long double	floatnum=ucs2charstring::convertToFloat(floatlit);

	stdoutput.printf("strings as numbers: %lld, %lld, %5.3Lf\n",
					intnum,uintnum,floatnum);
	stdoutput.write('\n');



	// identification of numeric strings...
	ucs2literal(n1,"1");
	ucs2literal(nm1,"-1");
	ucs2literal(n1p1,"1.1");
	ucs2literal(nm1p1,"-1.1");
	ucs2literal(none,"one");
	ucs2literal(nhello,"hello");

	const ucs2_t * const numbers[]={
		n1,nm1,n1p1,nm1p1,none,nhello,NULL
	};

	for (const ucs2_t * const *n=numbers; *n; n++) {
		char	*nstr=charstring::duplicateUcs2(*n);
		stdoutput.printf("%s %s a number\n",nstr,
				(ucs2charstring::isNumber(*n))?"is":"is not");
		stdoutput.printf("%s %s an integer\n",nstr,
				(ucs2charstring::isInteger(*n))?"is":"is not");
		delete[] nstr;
	}
	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",
				ucs2charstring::getIntegerLength(*i),*i);
	}
	stdoutput.write('\n');



	// dollar amounts
	ucs2literal(dollarstr,"$123.45");
	int64_t	pennies=ucs2charstring::convertAmount(dollarstr);
	ucs2_t	*dollars=ucs2charstring::convertAmount(pennies);
	char	*dollarstrstr=charstring::duplicateUcs2(dollarstr);
	char	*dollarsstr=charstring::duplicateUcs2(dollars);
	stdoutput.printf("%s as pennies: %lld\n",dollarstrstr,pennies);
	stdoutput.printf("%lld pennies as dollars: %s\n",pennies,dollarsstr);

	delete[] dollarstrstr;
	delete[] dollarsstr;
}

Encoding UCS-2 Character Strings

The ucs2charstring class also provides methods for escaping UCS-2 character strings.

#include <rudiments/ucs2charstring.h>
#include <rudiments/charstring.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	// backslash-escaping of quote, backslash and space characters...
	ucs2literal(path,"\"C:\\Program Files\\Firstworks\"");

	char	*pathstr=charstring::duplicateUcs2(path);
	stdoutput.printf("original path:\n  %s\n",pathstr);
	delete[] pathstr;

	ucs2literal(escchars,"\"\\ ");
	ucs2_t	*escapedpath=ucs2charstring::escape(path,escchars);
	char	*escapedpathstr=charstring::duplicateUcs2(escapedpath);
	stdoutput.printf("escaped path:\n  %s\n",escapedpathstr);
	delete[] escapedpathstr;

	ucs2_t	*unescapedpath=ucs2charstring::unescape(escapedpath);
	char	*unescapedpathstr=charstring::duplicateUcs2(unescapedpath);
	stdoutput.printf("unescaped path:\n  %s\n",unescapedpathstr);
	stdoutput.write('\n');

	delete[] unescapedpathstr;
	delete[] escapedpath;
	delete[] unescapedpath;
}
Copyright 2017 - David Muse - Contact