ssstring.txt (version 5.4 - 3/1/99) SSstring - A Subset and Superset of the STL string class Table of Contents ===================================================== 1.0 - Introduction 2.0 - The STL (Standard Template Library) String Class 3.0 - The sstring Class 4.0 - The Derived Class - kstring 5.0 - Files and Stuff 6.0 - General Information on sstring 7.0 - Public Members of sstring 8.0 - Public Member Functions of kstring 9.0 - Protected Members of sstring 10.0 - Memory Allocation Policy 1.0 - Introduction ================== Computer programming requires the manipulation of string variables. C and C++ programmers have traditionally used char * or char arrays with the assistance of string.h to manipulate string expressions. This method is cumbersome and error prone. Moreover, the functionality of string.h can be described as adequate at best. C++ can greatly resolve the problem with a "string" class. A variety of string classes have been developed by individuals and companies. The problem has been the lack of standardization. Now enters the ISO/ANSI C++ standard STL string class. Problems: availability, complexity, and shortcomings. Solution: SString. SSstring is a subset and superset of the STL string class. SSstring implements two classes: sstring - A 90% subset of the standard C++ STL string class as defined in the December 1996 draft of the ISO/ANSI C++ standard. sstring does not use templates. sstring only supports of strings containing characters of type "char". kstring - A derived class of sstring (or the standard string class) that adds features such as conversions between numeric and string types, token extraction and string formatting. The sstring class is intended for users who do not have access to the standard string class (Turbo C++ users) or for users who want a non-template string class with source code (works with precompiled headers of Borland C++). sstring, provides most of the conveniences of the STL and removes some of the problems and complexity. kstring is a superset of the sstring or the string classes. It is the recommended string class to use. kstring has capability of the standard string class plus some very useful bells and whistles. 2.0 - The STL (Standard Template Library) String Class ====================================================== The Standard Template Library (STL) provides a powerful method of dealing with strings. C-style strings are powerful, but they require control of many low-level items such as allocation sizes and pointer offsets. The STL string class is designed to increase the power available above that of C-strings, but without need for low-level concerns. Essentially the string class makes the programmers job easier. The syntax governing this class is simple and easy to use. Furthermore, the syntax is consistent with the STL function calls. There are numerous resources on the Web describing the Standard Template Library - a great starting point is http://www.sgi.com/Technology/STL/ The December 1996 draft of the ISO/ANSI C++ standard can be found at http://www.cygnus.com/misc/wp/ for info on standard. 3.0 - The sstring Class ======================= The sstring is a 90% subset of the standard C++ STL string class as defined in the December 1996 draft of the ISO/ANSI C++ standard. The sstring class provides a mechanism for manipulating strings. The manipulations are intuitive and easy to understand. For example, the source code to compare strings can be written as if comparing integers, because familiar comparison operators (such as ==, != ) are provided. An explicit function call is not needed to perform the comparison. Below is some intuitively obvious sstring code: sstring s1("Hello"); sstring s2("World"); sstring s3; s3 = s1 + " " + s2; cout << s3 + "!" << endl; This class allocates all memory and provides an explicit variable to track the sstring length. Thus, sstring length can be looked up in constant time, which is efficient for many sstring computations. This class handles memory allocations and knows the allocated size. Memory is allocated in blocks (default size is 16 bytes). For example, a sstring of length 12 is allocated 16 bytes of memory; a sstring of length 20 is allocated 32 bytes. Operations are checked against the current size, and the allocated size is decreased or increased when necessary. sstring supports strings of characters of type "char" only. It is a non-template subset of the STL string class. The sstring class automatically provides the terminating NULL character. 4.0 - The Derived Class - kstring ================================= The STL string class and the sstring class are great, but they lack some fundamental features. kstring is a derived class of sstring (or the standard string class) that adds features such as conversions between numeric and string types, token extraction and string formatting. For example the statement: ok = line.token(1).cvt_double(inches); converts the 1th token of line to a double and places the answer in inches. The bool ok is set to true if the conversion worked. kstring is a superset of the sstring or the string classes. It is the recommended string class to use. kstring has capability of the standard string class plus some very useful bells and whistles. 5.0 - Files and Stuff ================================ The files implementing sstring and kstring classes are named ssstring.h and ssstring.cpp. Sample code demonstrating sstring and kstring are included in: ss_dem1.cpp - a simple SSstring demo ss_dem2.cpp - a comprehensive demonstration SSstring. ss_demw.cpp - a Borland C++ OWL windows demo of SSstring SSstring is FREEWARE. SSstring was developed by : Tom Kisko - Associate in Industrial and Systems Engineering Wesley Day - Graduate student in Industrial and Systems Engineering Contact kisko@ise.ufl.edu to report bugs or make suggestions. THIS WORK IS PROVIDED ON AN "AS IS" BASIS. THE AUTHOR PROVIDES NO WARRANTY WHATSOEVER, EITHER EXPRESS OR IMPLIED, REGARDING THE WORK, INCLUDING WARRANTIES WITH RESPECT TO ITS MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. 6.0 - General Information on sstring ==================================== sstring objects consist of 0 to npos characters. npos defaults to 5000; change via ssstring.h. npos is used in current literature to represent "no position specified" Elements of sstring are numbered starting at 0, e.g., s[0] is the first element of the sstring, s. In any sample code below, presume identifiers that start with: s are of type sstring k are of type kstring cp are of type char * ch are of type char n, i, j are of type unsigned typedef size_t unsigned; // used also in current literature If you are using Turbo C++ 3.0 or any other compiler that does not have the bool type nor false and true constants, uncomment their declaration in ssstring.h, i.e. change: //typedef char bool; //enum {false, true}; to: typedef char bool; enum {false, true}; 7.0 - Public Members of sstring =============================== /////////////////// // Constructor functions /////////////////// sstring( ) default constructor; creates a zero length string. e.g., sstring s1(); // s1 contains "" sstring s1; // s2 contains "" sstring (const char * cp) construct a sstring from cp. e.g., sstring s2("ABCDEF"); // s2 contains "ABCDEF" sstring(const char * cp, size_t n) construct a sstring from cp taking a maximum of n characters or the length of the sstring. e.g., sstring s3("12345678",6); // s3 contains "123456" // given cp points to "abc123"; sstring s4(cp,8); // s4 contains "abc123" sstring(const sstring & s) constructor with a sstring as an initial value. referred to as the "copy constructor". e.g., sstring s5(s3); // s5 contains "123456" sstring(const sstring & s, size_t pos, // optional starting character size_t n_chars = npos) // optional number of characters construct a sstring from s starting at location pos (first location = 0) and continuing for the length of the sstring or for n_chars characters, whichever comes first. e.g., sstring s6(s5,0,3); // s6 contains "123" sstring(char ch, size_t n = 1); construct a sstring consisting of n copies of the character ch. e.g., sstring s7('*',5); // s7 contains "*****" sstring s8('b'); // s8 contains "b" /////////////////// // Destructor /////////////////// ~sstring(void) the destructor. /////////////////// // = operators /////////////////// sstring& operator = (const sstring & rhs) copy a sstring. e.g., s1 = s2; // s1 contains "ABCDEF" sstring& operator = (const char * rhs); set a sstring equal to a C-style character string pointed to by rhs. e.g., s1 = "abc123"; // s1 contains "abc123" sstring& operator = (const char rhs) set a sstring equal to a character. e.g., s1 = 'c'; // s1 contains "c" /////////////////// // Comparison operators /////////////////// NOTE: By default, compares are case sensitive. To make them case insensitive, add a line of code: sstring::case_sensitive = false; // the comparision of strings is case insensitive or kstring::case_sensitive = false; // the comparision of strings is case insensitive You may turn case sensitivity on and off whenever desired. friend bool operator == (const sstring & lhs, const sstring & rhs); friend bool operator == (const sstring & lhs, const char * rhs) friend bool operator == (const char * lhs, const sstring & rhs) friend bool operator != (const sstring & lhs, const sstring & rhs) friend bool operator != (const sstring & lhs, const char * rhs) friend bool operator != (const char * lhs, const sstring & rhs) friend bool operator > (const sstring & lhs, const sstring & rhs) friend bool operator > (const sstring & lhs, const char * rhs) friend bool operator > (const char * lhs, const sstring & rhs) friend bool operator < (const sstring & lhs, const sstring & rhs) friend bool operator < (const sstring & lhs, const char * rhs) friend bool operator < (const char * lhs, const sstring & rhs) friend bool operator <= (const sstring & lhs, const sstring & rhs) friend bool operator <= (const sstring & lhs, const char * rhs) friend bool operator <= (const char * lhs, const sstring & rhs) friend bool operator >= (const sstring & lhs, const sstring & rhs) friend bool operator >= (const sstring & lhs, const char * rhs) friend bool operator >= (const char * lhs, const sstring & rhs) e.g., s2 = "ABC"; s3 = "BC"; s5 = "123456"; s6 = "ZZZ"; cp="XYZ"; s7="abc"; if (s5 != s6) results in true if (s2 == "ABC") results in true if (s2 < s3) results in true - A is less than B if (s2 > s3) results in false if (cp < s6) results in true - X is less than Z if (s2 > s7) results in false - A is less than a sstring::case_sensitive = false; if (s2 == "aBc") results in true /////////////////// // Concatenating strings /////////////////// sstring& operator += (const sstring & rhs) concatenate rhs to a sstring. Memory is allocated and deleted as required. e.g., s1 = "z"; s2 = "ABC"; s1 += s2; // s1 contains "zABC" sstring& operator += (const char * rhs) concatenate the C-string to a sstring. See note on memory above. e.g., s1 = "ABC"; cp [] = "123"; s1 += cp; // s1 contains "ABC123" s1 += "XYZ"; // s1 contains "ABC123XYZ" sstring& operator += (const char rhs) concatenate the character to a sstring. See note on memory above. e.g., s1 = "ABC"; s1 += 'x'; // s1 contains "ABCx" friend sstring operator + (const sstring &lhs, const sstring &rhs) friend sstring operator + (const sstring &lhs, const char * rhs) friend sstring operator + (const char * lhs, const sstring &rhs) concatenate rhs to a sstring. lhs and rhs retain original data. e.g., s2 = "ABC"; s4 = "123"; c = 'W'; // cp points to "hey you" s2 + s4 // returns "ABC123" s4 + s2 // returns "123ABC" s2 + c // returns "ABCW" c + s2 // returns "WABC"; cp + s2 // returns "hey youABC" s2 + cp // returns "ABChey you" /////////////////// // Inserting characters into a sstring /////////////////// sstring& insert(size_t startInsertAt, const sstring& s, size_t startIndex = 0, size_t numChars = npos); at position startInsertAt in the implicit sstring, insert s beginning at startIndex for numChars characters. sstring& insert(size_t startInsertAt, const char* cp) at position startInsertAt in the implicit sstring, insert cp. sstring& insert(size_t startInsertAt, const char* cp, size_t numChars) at position startInsertAt in the implicit sstring, insert cp for numChars characters. sstring& insert(size_t startInsertAt, char ch, size_t numChars = 1) at position startInsertAt in the implicit sstring, insert ch characters numChars times. e.g., s2 is "ABCDEF"; s5 is "123456"; // cp points to "boy wonder" s2.insert(1,s5,1,3); // returns s2 = "A234BCDEF" s2 is now "A234BCDEF" s2.insert(4,cp,3); // returns s2 = "A234boyBCDEF" s2 is now "A234boyBCDEF" s2.insert(2,cp); // returns s2 = "A2boy wonder34boyBCDEF" s2 is now "A2boy wonder34boyBCDEF" s2.insert(1,'V',3); // returns s2 = "AVVV2boy wonder34boyBCDEF" /////////////////// // Removing characters within a sstring /////////////////// sstring& remove(size_t startIndex = 0, size_t numChars = npos) removes characters and collapses the sstring; starting at startIndex and continuing for numChars or till the end of the sstring. The January 96 working papers rename this erase. e.g., s1 = "ABCDEF"; s4 = "xyx 123 abc"; s1.remove(2,3); // returns "ABF" s4.remove(3,2); // returns "xyz23 abc" s1.remove(0,1); // returns "BF" s4.remove(4,3); // returns "xyz2bc" // What if you specify to remove more characters which are in the // sstring? The function adjusts for the error. s4.remove(3,300); // returns "xyz" // What if you specify a startIndex greater than the length of the // sstring? The function adjusts the startIndex back to the // beginning element. s1.remove(30,1); // returns "F" /////////////////// // Replacing characters within a sstring /////////////////// sstring& replace(size_t removeFrom, size_t removeCount, const sstring& s, size_t startReplacePosition = 0, size_t replaceCount = npos) replace invokes the following functions. remove(removeFrom, removeCount); insert(removeFrom, s, startReplacePosition, replaceCount); sstring& replace(size_t removeFrom, size_t removeCount, const char* cp) replace invokes the following functions. remove(removeFrom, removeCount); insert(removeFrom, cp); sstring& replace(size_t removeFrom, size_t removeCount, const char* cp, size_t replaceCount) replace invokes the following functions. remove(removeFrom, removeCount); insert(removeFrom, cp, replaceCount); sstring& replace(size_t removeFrom, size_t removeCount, char ch, size_t numChars = 1) replace invokes the following functions. remove(removeFrom, removeCount); insert(removeFrom, ch, numChars); e.g., s5 is "12345678"; s4 is "xyz"; // cp points to "boy wonder" s5.replace(1,5,s4,0,3); // returns s5 = "1xyz78" s5 is now "1xyz78" s5.replace(2,2,s4,5); // returns s5 = "1xxyz78" s5 is now "1xxyz78" s5.replace(0,3,cp); // returns "boy wonderyz78" /////////////////// // Addressing individual characters within a sstring /////////////////// char sstring::operator[ ](size_t pos) const return the pos'th character; s[0] is 1'st char; returns '\0' if pos is too big e.g., s0 = "WABCXYZW"; ch = s0[0]; // ch is 'W' ch = s0[100]; // ch is '\0' char & sstring::operator[ ](size_t pos); return a reference to the pos'th character. e.g., s0 = "WABCXYZW" s0[0] = 'x'; // changes s0 to "xABCXYZW" s0[1] = 'y'; // changes s0 to "xyBCXYZW" s0[2] = 'z'; // changes s0 to "xyzCXYZW" s0[100] = 'z'; // does nothing /////////////////// // Getting a substring from within a sstring /////////////////// sstring substr(size_t startIndex, size_t numChars) const; return a substring starting at startIndex and continuing for numChars characters or till the end of the sstring. e.g., s1 = "ABC123DEF456"; s1.substr(2,3) // returns "C12" sstring(s1,2,3) // returns "C12", another way to create a substring // What if the startIndex specified is greater than the sstring // length? The function returns an empty sstring. s2.substr(300,3); // returns "" // What if numChars specified is greater than the remaining length // of the sstring? The function adjusts and removes all characters // up to the NULL terminator. s2.substr(3,20); // returns "123DEF456" /////////////////// // Searching within a sstring /////////////////// size_t find(const sstring & s, size_t startIndex = 0) find the first location of s in a sstring starting at position startIndex. The location is relative to the beginning of the parent sstring. size_t find(const char * cp, size_t startIndex = 0) find the location of cp in a sstring starting at position startIndex. The location is relative to the beginning of the parent sstring. size_t find(char ch, size_t startIndex = 0) find the location of ch in a sstring starting at position startIndex. The location is relative to the beginning of the parent sstring. e.g., sstring s3 = "mississippi"; s6 = "ss"; s3.find("ss",0); // returns 2 s3.find("ss",2); // returns 5 s3.find(s6,3); // returns 5 s3.find('i',5); // returns 7 /////////////////// // Length of the sstring /////////////////// size_t length(void) returns the length of the sstring - does not include NULL terminator. e.g., s1 = "ABCDEF"; if (s1.length() > 10) doit(); // s1.length() returns "6", doit() will be called. /////////////////// // Copying to a C-style sstring /////////////////// size_t copy(char * cp, size_t numChars, size_t startIndex) const; the implicit sstring starting at startIndex is copied into cp for numChars characters or until \0 is reached; returns the number of characters copied e.g., s3 = "ABCDEFG"; cp points to "xyz" s3.copy(cp,2,3); // cp = "DEz", s3 remains "ABCDEFG" s3.copy(cp,2,1); // cp = "BCz", s3 remains "ABCDEFG" /////////////// // A char pointer to the contents of the sstring /////////////// const char * c_str(void) const; returns a C-style string pointer; use in legacy functions requiring char *. e.g., f.open(s1.c_str()); // c_str() is a pointer to the contents of s1 /////////////////// // I/O operations /////////////////// friend ostream& operator << (ostream &st, const sstring &s); output a sstring e.g., cout << s1 << ", " << s2 << endl; file_out << s1 << endl; friend istream& operator >> (istream &st, sstring &s2); read a token from istream into a sstring e.g., cin << s1; // warning: does not read the entire line, see getline friend istream& getline(istream& st, sstring& s, char ch = '\n'); read a line until ch is found; ch is then flushed from the stream e.g., getline(cin, s1); getline(file_in, s1); 8.0 - Public Member Functions of kstring ======================================== /////////////////// // Six base class constructors (just like sstring constructors) /////////////////// kstring(); default constructor; creates a zero length sstring e.g., kstring k1; // default constructor; k1 is "" kstring(const char * cp); constructor with a C-style string as an initial value e.g., kstring k2("wxyz"); // char * constructor; k2 is "wxyz" kstring(const char * cp, size_t n); constructor with a C-style string - copies n chars starting at cp e.g., kstring k3("123456",4); // char *,n constructor; k3 is "1234" kstring(const kstring & s); constructor with a kstring as an initial value e.g., kstring k4(k2); // copy constructor; k4 is duplicate of k2 kstring(const kstring & s, size_t pos, // starting position size_t n_chars = npos); // optional # of chars constructor with part of a kstring as an initial value e.g., kstring k5(k2,1,2); // substring constructor; k5 is "xy" kstring(char ch, size_t n = 1); constructor with a char as an initial val, repeated n times e.g., kstring k6('s',2); // char constructor; k6 is "ss" /////////////////// // Three additional kstring constructors /////////////////// kstring(long val, size_t width = 0, bool comma_fmt = false, char pad_ch = ' '); constructor with long as an init val; width=0 means no padding; if comma_fmt is set to true, commas are inserted into val; pad_ch is the padding character; e.g., long val_long 12345; long val_long2 = -1234567890; kstring k7(val_long); // k7 is "12345" kstring k8(val_long,8,false,'*'); // k8 is "***12345" kstring k9(val_long,0,true); // k9 is "12,345" kstring k10(val_long2,13); // k10 is " -1234567890" kstring k11(val_long2,0,true); // k11 is "-1,234,567,890" kstring k12(val_long2,18,true,'$'); // k12 is "$$$$-1,234,567,890" kstring(double val, size_t d = 2, size_t width = 0, char pad_ch = ' '); constructor with double as an initial val; d decimal digits; width = 0 means no padding; pad_ch is the padding character; e.g., double val2 = 123456.12345; kstring k13(val2); // k13 is "123456.12" kstring k14(val2,3); // k14 is "123456.123" kstring k15(val2,3,12,'*'); // k15 is "**123456.123" kstring k16(val2,3,12); // k16 is " 123456.123" kstring k17(val2,5,17,'$'); // k17 is "$$$$$123456.12345" kstring(const sstring & s); constructor with a base class (sstring object) as an initial value. an object of the derived class (kstring) can be assigned the value of the base class (sstring) ONLY if there is a constructor function in the derived class that accepts the base class (a sstring object) as an argument. e.g., sstring s1("xyz"); kstring k18(s48); // k18 = "xyz" /////////////////// // constructing a sstring from a kstring /////////////////// In object oriented programming, an object of the base class (sstring) can always be constructed from the value of a derived class (kstring). The copy constructor in the base class is used to perform the construction. e.g., kstring k19("abc"); sstring s2(k19); // s2 is "abc" /////////////////// // superset functions /////////////////// /////////////////// // kstring tokens /////////////////// int num_tokens(char delim = ' ') returns the number of tokens in kstring or 0 if none are found; the kstring "University of Florida in Gainesville" contains 5 tokens; returns the n'th token; n = 0 for first token; e.g., kstring k1("University of Florida, Gainesville, Florida"); n = k1.num_tokens(); // assigns 5 to n m = k1.num_tokens(','); // assigns 3 to m kstring token(int n, char delim = ' ', bool to_eos = false) returns the n'th token in a kstring or "" if one was not found; delim is the character separating, or delimiting, the tokens; if to_eos is true, returns the remainder of the kstring, starting at token n e.g., kstring k2("University of Florida, Gainesville, Florida"); k3 = k2.token(0); // assigns "University" to k3 k3 = k2.token(2); // assigns "Florida," to k3 k3 = k2.token(8); // assigns "" to k3, token doesn't exist k3 = k2.token(0,','); // assigns "University of Florida" to k3 k3 = k2.token(1,','); // assigns " Gainesville" to k3 k3 = k2.token(8,','); // assigns "" to k3, token doesn't exist /////////////////// // convert kstring to a number /////////////////// bool cvt_long(long & val) converts first nonblank characters in the kstring to a long number; returns true if there was a number. e.g., long val3; kstring k4("7000"); ok = k4.cvt_long(val3); // val3 is 7000; ok is true bool cvt_long(size_t & i, long & val) converts value at position i to a long value, val; updates i to position of next nonblank char after the number; returns true if there was a number. e.g., long val4, val5; size_t i = 0; kstring k5("15000 400"); ok = k5.cvt_long(i, val4); // val4 is 15000; i is 6 if (ok) ok = k9.cvt_long(i, val5); // val5 is 400; i is 9 bool cvt_double(double & val) converts first nonblank characters in the kstring to a double number; returns true if there was a number. e.g., double val6; kstring k6("43.21"); ok = k11.cvt_double(val6); // val6 is 43.21; ok is true bool cvt_double(size_t & i, double & val) converts the value at position i to a double value, val; updates i to position of next nonblank char after the number; returns true if there was a number. e.g., double val7, val8; size_t i = 0; kstring k7("12 345"); ok = k7.cvt_double(i, val7); // val7 is 12; i is 4 if (ok) ok = k7.cvt_double(i, val8); // val8 is 345; i is 7 /////////////////// // kstring formatting /////////////////// void trim_trail() trims the trailing spaces in a kstring. e.g., kstring k13(" Go Gators "); k13.trim_trail(); // k13 is " Go Gators" void trim_lead() trims the leading spaces in a kstring. e.g., kstring k14(" Go Gators "); k14.trim_lead(); // k14 is "Go Gators " void trim() trim leading and trailing spaces in a kstring. e.g., kstring k15(" Go Gators "); k15.trim(); // k15 is "Go Gators" kstring kstring::trim_of() trims leading and trailing spaces, but leave original string intact e.g., kstring k16(" Go Gators "); if (k1 == k15.trim_of()) // is k1 == "Go Gators"; k16 unchanged size_t pad(size_t width, char pad_ch= ' ', int side = ON_LEFT) pad on left (default) or on right (if side is true) to specified width; do nothing if width <= current length e.g., kstring k17("ABC"); k17.pad(6,'=',true); // k17 is "ABC===" kstring k18("12345"); k18.pad(10); // k18 is " 12345" kstring k19("12345"); k19.pad(5); // k19 is "12345" kstring kstring::pad_of(size_t width, char pad_ch, int side) pad on left (default) or on right (if side is true) to specified width; returns a modified object but original kstring remains the same. e.g., kstring k20("ABC"); k1 = k20.pad_of(6,'=',true); // k1 is "ABC==="; k20 is unchanged void l_just(size_t n) left justifies the first non-blank char in a kstring to a position of n. e.g., kstring k17("ABC"); k21.l_just(3); // k21 is " ABC" void r_just(size_t n) right justifies the kstring to a width of n. e.g., kstring k17("ABC"); k22.r_just(6); // k22 is " ABC" void center(size_t n) center the kstring at position n. e.g., kstring k17("ABC"); k23.center(4); // k23 is " ABC" kstring kstring::center_of(size_t n) returns centered kstring but leaves original kstring intact. e.g., kstring k24("ABC"); k1 = k24.center_of(4); // k1 is " ABC"; k24 is unchanged /////////////////// // kstring math operations /////////////////// kstring& kstring::dd_mm_ss_of(double val, size_t d = 0) converts val to "dd:mm:ss" format (degrees, minutes and seconds or hours, minutes and seconds); d is decimal digits in ss e.g., kstring k25; cout << k25.dd_mm_ss_of(11.42673); // displays 11:25:36 kstring k26; cout << k26.dd_mm_ss_of(11.42673, 3); // displays 11:25:36.228 double kstring::deg_of(void) returns the double equivalent of a kstring in the form dd:mm:ss e.g., kstring k27("11:25:36.228"); cout << k27.deg_of() << endl; // displays 11.42673 kstring k28("11:30"); cout << k28.deg_of() << endl; // displays 11.5 /////////////////// // convert case /////////////////// void to_upper() convert kstring to uppercase. e.g., kstring k28("Abc 123") k28.to_upper(); // k28 is "ABC 123" void to_lower() convert kstring to lowercase. e.g., kstring k29("Abc 123") k29.to_lower(); // k29 is "abc 123" kstring kstring::upper_of() returns a kstring object converted to uppercase; original is unchanged e.g., kstring k30("q"); if (k30.upper_of() == "Q") // is k30 a Q?; k30 is unchanged kstring kstring::lower_of() returns a kstring object converted to lowercase. e.g., kstring k31("Q"); if (k31.lower_of() == "q") // is k31 a Q?; k31 is unchanged 9.0 - Protected Members of sstring ================================== char * str_ptr pointer to the current string. size_t len length of the string. size_t res current reserved area in memory - always divisible by block_size. static const size_t block_size smallest unit of allocated memory - 16 bytes for this class. static const size_t read_buffer_size smallest unit of memory allocated to read a string from the keyboard static const size_t npos no position specified - why npos? it's used in the current C++ literature 10.0 - Memory Allocation Policy =============================== Dynamic memory, or memory created and destroyed during program execution, is handled by the class. No memory management is required by the user. Memory allocation for this sstring class employs a "current sstring size allocation algorithm". Memory is allocated in block sizes of 16 bytes. For example, a string with a length of 8 is allocated 16 bytes of memory. A string of length 14 is allocated 16 bytes; a string of length of 20 is allocated 32 bytes; a string of length of 36 is allocated 48 bytes. If the size of the sstring should increase, the allocation size is adjusted accordingly. If the size of the sstring should decrease, the allocation size is adjusted accordingly. If the sstring changes requiring the same block size, no action is taken. Furthermore, to prevent memory leaks, any deletion of old memory is handled by the class. The 16 byte block size can be adjusted - it was chosen because that is the memory allocation quantum of Turbo C++ 3.0.