resize() and size()
rfind()
substr()
char_traits Class
char_traits Class Typedefs
char_traits Class Member Functions
char_traits assign() example
char_traits compare() example
char_traits copy() example
char_traits, eof() example
My Training Period: xx hours
This is a continuation from the previousC++ STL String & Character manipulation. Program examples in this Module compiled usingVisual C++ 6.0 with SP6 andVisual C++ .Net. Some program examples may generate warning and runtime errors caused by buffer/stack overflow. The good compilers have some protection for errors :o). g++ (run on Fedora 3 machine) examples, given at the end of this Module. The source code for this tutorial is available atC++ Characters & Strings source codes.
|
| The C++ string class programming abilities that supposed to be acquired:
A continuation from previous Module…
resize() and size()
// resize() and size() #include <string> #include <iostream> using namespace std;
int main() { string str1("Testing the resize()"); cout<<"str1 string is: "<<str1<<endl; basic_string <char>::size_type SizeStr1; SizeStr1 = str1.size(); basic_string <char>::size_type CapaStr1; CapaStr1 = str1.capacity(); // compare size & capacity of the original string cout<<"The size of str1 string is: "<<SizeStr1<<endl; cout<<"The capacity of str1 string is: "<<CapaStr1<<endl; // use resize() to increase size by 3 elements of the question mark cout<<"\nOperation: str1.resize(str1.size() + 3, '?')"<<endl; str1.resize(str1.size() + 3, '?'); cout<<"The resized str1 string is: "<<str1<<endl; SizeStr1 = str1.size(); CapaStr1 = str1.capacity(); // compare size & capacity of a string after resizing cout<<"The size of resized str1 string is: "<<SizeStr1<<endl; cout<<"The capacity of resized str1 string is: "<<CapaStr1<<endl; // use resize() to increase size by 10 elements: cout<<"\nOperation: str1.resize(str1.size() + 10)"<<endl; str1.resize(str1.size() + 10); cout<<"The resized str1 string is: "<<str1<<endl; SizeStr1 = str1.size(); CapaStr1 = str1.capacity(); // compare size & capacity of a string after resizing note capacity increases automatically as required cout<<"The increased size of str1 string is: "<<SizeStr1<<endl; cout<<"The increased capacity of str1 string is: "<<CapaStr1<<endl; // use resize() to downsize by 20 elements: cout<<"\nOperation: str1.resize(str1.size() - 20)"<<endl; str1.resize(str1.size() - 20); cout<<"The downsized str1 string is: "<<str1<<endl; SizeStr1 = str1.size(); CapaStr1 = str1.capacity(); // compare size & capacity of a string after downsizing cout<<"The size of downsized str1 string is: "<<SizeStr1<<endl; cout<<"The capacity of downsized str1 string is: "<<CapaStr1<<endl; return 0; }
|

The return value is the index of the last occurrence when searched backwards, of the first character of the substring when successful; otherwisenpos.
// reversed find, rfind() part I
#include <string>
#include <iostream>
using namespace std;
int main()
{
// searching for a single character in a string
string str1("Testing the rfind() 1..2..3");
cout<<"str1 string is: "<<str1<<endl;
basic_string <char>::size_type index1, index2;
static const basic_string <char>::size_type npos = -1;
cout<<"Operation: str1.rfind('i', 18)"<<endl;
index1 = str1.rfind('i', 18);
if(index1 != npos)
cout<<"The index of the 1st 'i' found before\nthe 18th position in str1 is: "<<index1<<endl;
else
cout<<"The character 'i' was not found in str1."<<endl;
cout<<"\nOperation: str1.rfind('z')"<<endl;
index2 = str1.rfind('z');
if(index2 != npos)
cout<<"The index of the 'z' found in str1 is: "<<index2<<endl;
else
cout<<"The character 'z' was not found in str1."<<endl;
cout<<endl;
// ----------------------------------------------------------------
// searching a string for a substring as specified by a C-string
string str2("Testing the rfind() 123");
cout<<"The str2 string is: "<<str2<<endl;
basic_string <char>::size_type index3, index4;
const char *cstr1 = "find";
cout<<"Operation: str2.rfind(cstr1, 25)"<<endl;
index3 = str2.rfind(cstr1, 25);
if(index3 != npos)
cout<<"The index of the 1st element of 'find' before\nthe 25th position in str2 is: "<<index3<<endl;
else
cout<<"The substring 'find' was not found in str2."<<endl;
const char *cstr2 = "nofind()";
cout<<"\nOperation: str2.rfind(cstr2, 25)"<<endl;
index4 = str2.rfind(cstr2, 25);
if(index4 != npos)
cout<<"The index of the 1st element of 'nofind()' before\n the 25th position in str3 is: "<<index4<<endl;
else
cout<<"The substring 'nofind()' was not found in str2."<<endl;
return 0;
}

// reversed find, rfind() part II
#include <string>
#include <iostream>
using namespace std;
int main()
{
// searching a string for a substring as specified by a C-string
string str3("Another test. Testing the rfind() the 123");
cout<<"The str3 string is: "<<str3<<endl;
static const basic_string <char>::size_type npos = -1;
basic_string <char>::size_type index5, index6;
const char *cstr3 = "test";
cout<<"Operation: str3.rfind(cstr3)"<<endl;
index5 = str3.rfind(cstr3);
if(index5 != npos)
cout<<"The index of the 1st element of 'test' in str3 is: "<<index5<<endl;
else
cout<<"The substring 'test' was not found in str3."<<endl;
const char *cstr4 = "the";
cout<<"\nOperation: str3.rfind(cstr4, index5 + 20, 2)"<<endl;
index6 = str3.rfind(cstr4, index5 + 20, 2);
if(index6 != npos)
cout<<"The index of the next occurrence of 'the' in str3 begins at: "<<index6<<endl;
else
cout<<"There is no next occurrence of 'the' in str3"<<endl;
cout<<endl;
// ----------------------------------------------------------
// searching string for a substring as specified by a string
string str4("Final rfind() testing 1...2...3");
cout<<"The str4 string is: "<<str4<<endl;
basic_string <char>::size_type index7, index8;
string str5("2...3");
cout<<"Operation: str4.rfind(str5, 30)"<<endl;
index7 = str4.rfind(str5, 30);
if(index7 != npos)
cout<<"The index of the 1st element of '1...2' before\nthe 30th position in str4 is: "<<index7<<endl;
else
cout<<"The substring '1...2' was not found in str4\nbefore the 30th position."<<endl;
string str6("...3");
cout<<"\nOperation: str4.rfind(str6)"<<endl;
index8 = str4.rfind(str6);
if(index8 != npos)
cout<<"The index of the 1st element of '...3' in str4 is: "<<index8<<endl;
else
cout<<"The substring '...3' was not found in str4."<<endl;
return 0;
}
Output:

The return value is a substring object that is a copy of elements of the string operand beginning at the position specified by the first argument.
// substr()
#include <string>
#include <iostream>
using namespace std;
int main()
{
string str1("Testing the substr()");
cout<<"str1 string is: "<<str1<<endl;
cout<<"\nOperation: str1.substr(4, 7)"<<endl;
basic_string <char> str2 = str1.substr(4, 7);
cout<<"The substring str1 copied is: "<<str2<<endl;
cout<<"\nOperation: str1.substr()"<<endl;
basic_string <char> str3 = str1.substr();
cout<<"The default str3 substring is: "<<str3<<"\nwhich is the original string."<<endl;
return 0;
}

26.2 char_traits Class
template <class CharType> struct char_traits;
CharType is the type of the data element.
|
The following table is a list of the char_traits class template typedef, the synonym name.
Typedef | Brief Description |
char_type | A type of character. |
int_type | An integer type that can represent a character of type char_type or an end-of-file (EOF) character. |
off_type | An integer type that can represent offsets between positions in a stream. |
pos_type | An integer type that can represent positions in a stream. |
state_type | A type that represents the conversion state in for multibyte characters in a stream. |
Table 26.1: char_traits typedef | |
The following table is a list of the char_traits class template member function.
Member Function | Brief Description |
assign() | Assigns one character value to another. |
compare() | Compares up to a specified number of characters in two strings. |
copy() | Copies a specified number of characters from one string to another. |
eof() | Returns the end-of-file (EOF) character. |
eq() | Tests whether twochar_type characters are equal. |
eq_int_type() | Tests whether two characters represented as int_types are equal. |
find() | Searches for the first occurrence of a specified character in a range of characters. |
length() | Returns the length of a string. |
lt() | Tests whether one character is less than another. |
move() | Copies a specified number of characters in a sequence to another, possible overlapping sequence. |
not_eof() | Tests whether a character is the end-of-file (EOF) character. |
to_char_type() | Converts an int_type character to the corresponding char_type character and returns the result. |
to_int_type() | Converts a char_type character to the corresponding int_type character and returns the result. |
Table 26.2: char_traits class template member functions | |
Note: The following program example may generate a runtime error regarding the buffer overflow, because there are no explicit exception handling code used in the program, the exceptions should be ‘fully’ handled by the compiler. Good compiler should warn us regarding the exceptions. If the problem persists, try changing some of the pointer variables to array variables as shown inmove() program example. It should be OK.
assign()
// char_traits, assign()
#include <string>
#include <iostream>
using namespace std;
int main()
{
// assigning a character value to another character
char chr1 = 'P';
const char chr2 = 'Q';
cout<<"The initial characters (chr1, chr2) are: ("<<chr1<<","<<chr2<<")"<<endl;
cout<<"Operation: assign(chr1, chr2)"<<endl;
char_traits<char>::assign(chr1, chr2);
cout<<"The new characters (chr1, chr2) are: ("<<chr1<< ", "<<chr2<<")"<<endl;
// assigning character values to initial part of a string
char_traits<char>::char_type* str1 = "Testing assign()";
char_traits<char>::char_type* result;
cout<<"\nThe target string str1 is: "<<str1<<endl;
cout<<"Operation: assign(str1, 5, \'#\')"<<endl;
result = char_traits<char>::assign(str1, 5, '#');
cout<<"The result = "<<result<<endl;
return 0;
}
Output:

The comparison between the strings is made element by element, first testing for equality and then, if a pair of elements in the sequence tests not equal, they are tested for less than.
If two strings compare equal over a range but one is longer than the other, then the shorter of the two is less than the longer one.
The return value is a negative value if the first string is less than the second string, 0 if the two strings are equal, or a positive value if the first string is greater than the second string.
// char_traits, compare()
#include <string>
#include <iostream>
using namespace std;
int main()
{
char_traits<char>::char_type* str1 = "TEST";
char_traits<char>::char_type* str2 = "RETEST";
char_traits<char>::char_type* str3 = "RETEST";
char_traits<char>::char_type* str4 = "TESTING";
cout<<"str1 string is: "<<str1<<endl;
cout<<"str2 string is: "<<str2<<endl;
cout<<"str3 string is: "<<str3<<endl;
cout<<"str4 string is: "<<str4<<endl;
cout<<"\nOperation: Comparison..."<<endl;
int comp1, comp2, comp3, comp4;
comp1 = char_traits<char>::compare(str1, str2, 2);
comp2 = char_traits<char>::compare(str2, str3, 3);
comp3 = char_traits<char>::compare(str3, str4, 4);
comp4 = char_traits<char>::compare(str4, str3, 4);
cout<<"compare(str1, str2, 2) = "<<comp1<<endl;
cout<<"compare(str2, str3, 3) = "<<comp2<<endl;
cout<<"compare(str3, str4, 4) = "<<comp3<<endl;
cout<<"compare(str4, str3, 4) = "<<comp4<<endl;
return 0;
}

Note: The following program example may generate a runtime error regarding the buffer overflow, because there are no explicit exception handling code use in the program, the exceptions should be ‘fully’ handled by the compiler. Good compiler should warn us regarding the exceptions. If the problem persists, try changing some of the pointer variables to arrays variables as shown in move() program example. It should be OK.
The source and destination character sequences must not overlap. Compare with the move() member function.
// char_traits, copy()
#include <string>
#include <iostream>
using namespace std;
int main()
{
char_traits<char>::char_type* str1 = "Testing the copy()";
char_traits<char>::char_type* str2 = "Fucking";
char_traits<char>::char_type* result;
cout<<"The str1, source string is: "<<str1<<endl;
cout<<"The str2, destination string is: "<<str2<<endl;
cout<<"\nOperation: copy(str1, str2, 7)"<<endl;
result = char_traits<char>::copy(str1, str2, 7);
cout<<"The result is: "<<result<<endl;
return 0;
}

The return value is a value that represents end of file character (such asEOF or WEOF).
If the value is represented as type char_type, it must correspond to no valid value of that type.
// char_traits, eof()
#include <string>
#include <iostream>
using namespace std;
int main( )
{
char_traits <char>::int_type int0 = char_traits<char>::eof();
cout<<"The eof return is: "<<int0<<endl;
char_traits<char>::char_type chs = 'R';
char_traits<char>::int_type int1;
int1 =char_traits<char>::to_int_type(chs);
cout<<"char_type chs "<<chs<<" = to int_type "<<int1<<endl;
char_traits <char>::int_type int2 = char_traits<char>::eof();
cout<<"The eof return is: "<<int2<<endl;
return 0;
}

tenouk C++ STL String class programming tutorial
The source code for this tutorial is available atC++ Characters & Strings source codes.
Acomplete C++ Standard Library documentation that includes STL.
Check thebest selling C/C++ books at Amazon.com.