Strings


Standards<ToolKit> includes comprehensive support for regular and wide-character (international) strings. It includes an implementation of the standard, templatized ANSI/ISO string, optimized for multithreaded environments.

Helper<ToolKit> provides extensions for substring support, and a tokenizer object that can easily break a string into its individual tokens.

The rest of this chapter describes each of these facilities in detail.

basic_string

The Standards<ToolKit> string is based on the template called basic_string. Unlike most other commercially available strings, basic_string uses two template parameters to define the following.

Although a template can create a wide variety of different strings, most C++ programs only require a couple of common string types. Standards<ToolKit> includes the following typedef s that handle most situations.

// Regular string of characters.
typedef
basic_string< char, string_char_traits_char, allocator<char> > string

// Regular string of wide characters.
typedef
basic_string< wchar_t, string_char_traits<wchar_t>, allocator<wchar_t> >
wstring

The string_char_traits class is a standard template class containing the default behaviors for a string's traits. The string_char_traits_char class is derived from the string_char_traits class containing specialized behaviors for a string of regular chars . The header file <ospace/string/traits.h> contains the definition of these trait classes.

To enhance readability, this reference page only documents the string specialization of basic_string . The interface for wstring is identical to that of string , except wchar_t is used in place of char .

The following example creates a string and accesses its individual elements.

Example <ospace/string/examples/string1.cpp>
#include <iostream>
#include <string>

void
main()
  {
  string string = "Lotus"; // Simple initialization.
  cout << "string = " << string << endl;

  size_t size = string.size(); // Obtain size of string.
  cout << "string.size() = " << size << endl;

  for ( size_t i = 0; i < size; i++ ) // Display individual characters.
    cout << "string[ " << i << " ] = " << string[ i ] << endl;

  for ( size_t j = 0; j < size; j++ ) // Illustrate assignment.
    string[ j ] = `x';
  cout << "string = " << string << endl;
}

string = Lotus
string.size() = 5
string[ 0 ] = L
string[ 1 ] = o
string[ 2 ] = t
string[ 3 ] = u
string[ 4 ] = s
string = xxxxx

You can compare strings using either the familiar relational operators or the compare() function. The following example uses both methods.

Example <ospace/string/examples/string2.cpp>
#include <iostream>
#include <string>

void
main()
  {
  string string1 = "adam";
  string string2 = "zacharia";
  cout
    << string1 << " > " << string2 << " = "
    << (string1 > string2) << endl;

  int compare = string1.compare( string2 ); // Similar to strcmp().
  cout << "compare = " << compare << endl;
  cout
    << string2 << " > " << string1 << " = "
    << (string2 > string1) << endl;

  compare = string2.compare( string1 );
  cout << "compare = " << compare << endl;
  cout
    << string1 << " > " << string1 << " = "
    << (string1 > string1) << endl;

  compare = string1.compare( string1 );
  cout << "compare = " << compare << endl;
  cout
    << "`adam' > " << string2 << " = "
    << ("adam" > string2) << endl;
}

adam > zacharia = 0
compare = -1
zacharia > adam = 1
compare = 1
adam > adam = 0
compare = 0
'adam' > zacharia = 0

You can append, insert, find, remove, and replace strings. The following example contains a single example of each of these operations.

In this example, many of the string functions return the value npos when they fail rather than -1. The value npos is defined as the largest number a size_t can represent, and is used as both an input value and a return value. When functions return this value, it typically means something was not found, such as a specific character, an index of a character, and so on.

Example <ospace/string/examples/string3.cpp>
#include <iostream>
#include <string>

void
main()
  {
  // Appending, searching, replacing, inserting.
  string string = "hello";
  cout << "string = " << string << endl;
  cout << string.size() << endl;

  string += " old chap"; // Append a string.
  cout << "string = " << string << endl;
  cout << string.size() << endl;

  // Insert string before character at index 6.
  string.insert( 6, "there " );
  cout << "string = " << string << endl;
  cout << string.size() << endl;

  int i = string.find( "old chap" ); // Get index of string.
  cout << "Found `old chap' at index " << i << endl;

  string.remove( i, 8 ); // Remove eight characters starting at index i.
  cout << "string = " << string << endl;
  cout << string.size() << endl;

  string.replace( 6, 5, "goodbye" ); // Replace 5 chars at index 6.
  cout << "string = " << string << endl;
  cout << string.size() << endl;
}

str = hello
str = hello old chap
str = hello there old chap
Found 'old chap' at index 12
str = hello there
str = hello goodbye

The string class does not contain an implicit const char* conversion operator. To use a string where a const char* is expected, use c_str() , which returns a pointer to a null-terminated (ASCII 0 terminated) array of the string's data.

Example <ospace/string/examples/string4.cpp>
#include <iostream>
#include <string>
#include <string.h> // For strlen().

void
main()
  {
  string string = "hello";
  const char* c_str = string.c_str(); // View as a "C" string.
  size_t len = strlen( c_str ); // Call "C" function to get its length.
  for ( size_t i = 0; i < len; i++) // Display all elements.
    cout << "c_str[ " << i << " ] = " << c_str[i] << endl;
}

c_str[ 0 ] = h
c_str[ 1 ] = e
c_str[ 2 ] = l
c_str[ 3 ] = l
c_str[ 4 ] = o

By default, a string's storage space is increased on demand. If you can anticipate how large a string will grow, you can use reserve() to preallocate storage space for the string. This prevents unnecessary reallocation of the string's storage as it grows toward its ultimate size. If you simply want to expand or truncate a string, use resize() instead.

In the following example, although the string grows to eight characters and ends with the substring "dog", the string is only printed up to its first null character.

Example <ospace/string/examples/string6.cpp>
#include <iostream>
#include <string>

void
main()
  {
  string string = "catty";
  cout << "string = " << string << ", size = " << string.size() << endl;

  string.resize( 3 ); // Truncate to 3 chars.
  cout << "string = " << string << ", size = " << string.size() << endl;

  string.resize( 5 ); // Expand to 5 chars, padding with NUL chars.
  string += "dog"; // 2 NULs remain between "cat" and "dog".
  cout << "string = " << string << ", size = " << string.size() << endl;

  string.reserve( 100 ); // Reserve 100 chars for future growth.
  cout << "string = " << string << ", size = " << string.size() << endl;
}

string = catty, size = 5
string = cat, size = 3
string = cat, size = 8
string = cat, size = 8

Iterators with Strings

For compatibility with STL, you can obtain an iterator at an extremity using begin() or end() . You can apply any of the standard STL algorithms to a string, such as sort() and reverse() , using this interface. For a complete description of iterators, consult Iterators in this manual.

The following example illustrates the use of iterators and a couple of STL algorithms.

Example <ospace/string/examples/string7.cpp>
#include <iostream>
#include <algorithm>
#include <string>

void
main()
  {
  string str = "the quick brown fox";
  string::iterator i;
  cout << "iterate forwards = ";
  for ( i = str.begin(); i != str.end(); i++ )
    cout << *i;
  cout << endl;
  cout << "reversed = ";

  reverse( str.begin(), str.end() ); // Reverse the str.
  cout << str << endl;
  cout << "sorted = ";

  sort( str.begin(), str.end() ); // Sort the str.
  cout << str << endl;
}

iterate forwards = the quick brown fox
reversed = xof nworb kciuq eht
sorted =    bcefhiknooqrtuwx

Using Strings in a Multithreaded Environment

Following is the list of rules governing legal string access in a multithreaded environment.

In other words, a string can have multiple readers or a single writer at any point in time.

The string class makes no attempt to enforce these rules; if two threads write to a single string at the same time, internal memory can be corrupted. If you want to enforce these rules manually, consider the os_monitor class provided in Thread<ToolKit>. For more information about Thread<ToolKit>, consult the Foundations User Guide and Reference Manual.


Copyright©1994-2026 Recursion Software LLC
All Rights Reserved - For use by licensed users only.