Characters
Header <cctype> - Character Type Library
The <cctype>
character type header (ported from C' <ctype.h>
), contains the following character handling functions.
FUNCTION | EXAMPLE |
---|---|
int isalpha (int ch); Return 1 if ch is alphabetic; and 0 otherwise int isdigit (int ch); Return 1 if ch is a digit [0-9]; and 0 otherwise int isalnum (int ch); Return 1 if ch is an alphabet or digit; and 0 otherwise int isxdigit (int ch); Return 1 if ch is a hexadecimal digit [0-9A-Fa-f]; and 0 otherwise |
|
int isupper (int ch); Return 1 if ch is in uppercase; and 0 otherwise int islower (int ch); Return 1 if ch is in lowercase; and 0 otherwise |
|
int toupper (int ch); Return the uppercase of ch int tolower (int ch); Return the lowercase of ch |
|
int isspace (int ch); Return 1 if ch is a white space (blank ' ', carriage return '\r', newline '\n', tab '\t', form feed '\f', vertical tab '\v') and 0 otherwise int ispunct (int ch) punctuation character? int iscntrl (int ch) control character? int isprint (int ch) printable character? int isgraph (int ch) graphical representation? |
|
All these functions treat a char
as a signed int
.
Strings: The C-String and the string class
Recall that C++ supports two types of strings:
- The C-style string (or C-String) in header
cstring
(ported over from C'sstring.h
), which represents a string as achar
array terminated by a null character'\0'
(or 0) (null-terminated char array). - The new C++
string
class in headerstring
.string
is a regular class, with public interface defined in the constructors and public member functions.
C-String Literals
A string literal such as "hello"
is treated as "an array of n
const
char
", terminated with the null '\0'
character (equivalent to 0), where n
is the length of the array including the terminating null character.
int main() { char * str1 = "hello"; // warning: deprecated conversion from string constant to 'char*' char * str2 = const_cast<char *>("hello"); // remove the "const" const char * str3 = "hello"; // *(str3 + 1) = 'a'; // error: assignment of read-only location '*(str3 + 1u)' char str4[] = "hello"; str4[1] = 'a'; const char str5[] = "hello"; // str5[1] = 'a'; // error: assignment of read-only location 'str5[1]' }
Take note that you cannot modify the content pointed to by const char *
.
C-String Headers and Functions
C-string (null-terminated char
array) can be declared as char*
or char[]
. This is because C treats an array name as a pointer to the first element of the array. Unlike regular arrays, there is no need to pass the length of C-string into function, as the function can deduce the length from the terminating null character.
C-String Functions in <cstring> header
The <cstring>
header (ported from C's string.h
) contains these commonly-used functions to operate on C-strings.
FUNCTION | EXAMPLE |
---|---|
size_t strlen (const char * cstr)
Return the length of cstr, excluding terminating null character '\0'.
size_t is typically typedef of unsigned int. |
char * msg = "Hello";
cout << strlen(msg); // length of string
|
// Copying char * strcpy (char * dest, const char * src) Copy src into dest, return dest char * strncpy (char * dest, const char * src, size_t n) Copy at most n characters from src into dest, return dest |
|
// Comparison int strcmp (const char * cstr1, const char * cstr2) Compare cstr1 and cstr2. Return 0 if cstr1 is equal to cstr1, less than zero (usually -1) if cstr1 is less than cstr2, more than zero (usually 1) if cstr1 is more than cstr2. int strncmp (const char * cstr1, const char * cstr2, size_t n) Compare up to n characters. |
|
// Concatenation char * strcat (char * dest, const char * src) Append src to dest, return src. char * strncat (char * dest, const char * src, size_t n) Append at most n characters from src into dest, return src. |
|
// Searching char * strchr (char * cstr, int ch); Return a pointer to the first occurrence of character char * strrchr (char * cstr, int ch); Return a pointer to the last occurrence of character char * strstr (char * cstr1, char * cstr2); Return a pointer to the first occurrence of cstr2 in cstr1 size_t strspn (const char * cstr, const char * accept) Return the length (span) of the initial portion of cstr which consists of only characters in accept char * strpbrk (char * cstr, const char * accept) Similar to strspn, but string pointer break returns a pointer to the first occurrence in cstr of any char in accept size_t strcspn (const char * cstr, const char * reject) Complement of strspn. Return the length of the initial portion of cstr, which does not have char in reject |
|
// Tokenizing char * strtok (char * cstr, const char * delim) Tokenize cstr with delim as the delimiters |
|
[TODO] example
C-String Functions in <cstdlib> header
The <cstdlib>
header (ported from C's <stdlib.h>
) contains functions to convert C-strings to fundamental types.
FUNCTION | EXAMPLE |
---|---|
int atoi (char * cstr) Parse C-string cstr into an int double atof (char * cstr) Parse C-string cstr into a double long atol (char * cstr) Parse C-string cstr into a long int long long atoll (char * cstr) Parse C-string cstr into a long long int |
|
double strtod (const char * cstr, char** endptr)
Parse C-string cstr into a double. If endptr is not a null pointer,
set the endptr to the first character after the number
float strtof (const char * cstr, char** endptr)
long strtol (const char * cstr, char** endptr)
long double strtold (const char * cstr, char** endptr)
long long strtoll (const char * cstr, char** endptr)
unsigned long long strtoull (const char * cstr, char** endptr) |
|
[TODO] example
C-String Input/Output Functions in <iostream> Header
The <iostream>
supports these functions for c-string input and output:
FUNCTION | EXAMPLE |
---|---|
cin >> var Read a word (delimiter by space) |
char *msg; cin >> msg; |
cin.getline(char * cstr, unsigned int n) cin.getline(char * cstr, unsigned int n, char delim) Read n-1 characters ('\0' appended) or till delimiter is reached. The delimiter character is not stored. |
char msg[256]; cin.getline(msg, 256); cin.getline(msg, 256, '\n'); |
int cin.get(): Return the next character, casted as an int. |
|
cin.peek(): return the next character (casted as an int), but not removing it from the input stream. |
|
cin.ignore(unsigned int n = 1, int delim = EOF): Remove n-1 characters from the input stream, or until delimiter is reached. |
cin.ignore(256, ' '); // Skip next word cin.ignore(1000, '\n'); // Flush input buffer |
Converting C-string to Uppercase/Lowercase
You probably have to write your own function using cctype
's toupper()
and tolower()
, which converts individual character. For example,
inline void strtoupper(char* str) { while (*str) { *str = toupper(*str); ++str; } }
The C++'s string class
The string
class, in header <string>
and under namespace std
(i.e., std::string
), models character sequences. The string
class is an instantiation of the basic_string<T>
template class that uses char
type with a typedef
.
typedef basic_string<char> string; typedef basic_string<wchar_t> wstring;
string Class Constructors
string (); // (1) Default constructor: construct an empty string of length 0. string (const string & str); // (2) Copy constructor: construct by copying str (by value) string (const string & str, size_t pos, size_t len = npos); // (3) Substring constructor: copy the substring starting at pos, of the len. // size_t is usually typedef to unsigned int // npos is a static constant in string (i.e., string::npos), // which holds the maximum value of size_t. string (const char * cstr); // (4) C-string: construct by copying the C-string. string (const char * cstr, size_t len); // (5) C-string buffer: construct by copying the cstr for len string (size_t len, char c); // (6) Fill Constructor: fill len with char c template <class Iterator> string (Iterator first, Iterator last); // (7) Iterator: copy the char in [first, last) string (initializer_list<char> initList); // (C++11)(8) Initializer list string (string && str) noexcept; // (C++11)(9) Move Constructor
Example,
string str1("apple");
string str2 = orange;
// '=' is not an assignment, but an implicit call to string's
// constructor str2("orange");
You cannot construct a string
from char
, int
or double
.
Example: string Constructor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <iostream> #include <string> // C++ string class #include <cstring> // C-string using namespace std; int main() { char cstr[] = "hello world!"; // C-string literal string s1; // (1) Default constructor cout << s1.length() << endl; // 0 cout << s1.size() << endl; // 0 - length() and size() are synonyms string s4(cstr); // (4) C-string s4[1] = 'E'; // [] does not perform index bound check cout << s4 << endl; // "hEllo world!" string s2(s4); // (2) Copy constructor s2.at(0) = 'H'; // at() does index-bound check // at() can be used on RHS cout << s2 << endl; // "HEllo world!" cout << s4 << endl; // no change - copy by value string s3a(s4, 2); // (3) Substring cout << s3a << endl; // "llo world!" s3a += " again"; // Append cout << s3a << endl; // "llo world! again" string s3b(s3a, 4, 3); // (3) Substring cout << s3b << endl; // "wor" string s5a(cstr, strlen(cstr)); // (5) C-string buffer cout << s5a << endl; // "hello world!" string s5b(cstr, 15); // (5) C-string buffer cout << s5b << endl; // "hello world! ??" // If len > length of cstr, garbage copied string s6(5, '$'); // (6) Fill constructor cout << s6 << endl; // "$$$$$" string s7a(cstr, cstr + 4); // (7) Iterator cout << s7a << endl; // "hell" // cstr1 is char*. Instantiate type parameter Iterator to char* // string s7b(s4, s4 + 2); // error: no match for 'operator+' in 's4 + 2' // s4 is a string object, not char* string s7c(&s4[0], &s4[2]); // (7) Iterator // &s4[0] and &s4[2] are char* cout << s7c << endl; // "hE" string s7d(s4.begin(), s4.end()); // begin() returns an iterator pointing to the first character // end() returns an iterator pointing to past-the-end character cout << s7d << endl; // "hEllo world!" } |
Example: C++11 string Constructor
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <string> // C++ string class using namespace std; int main() { // To compile with option -std=c++0x string str1 = {'a', 'p', 'p', 'l', 'e'}; // (8) C++11 Initializer List cout << str1 << endl; // "apple" string str2 {'o', 'r', 'a', 'n', 'g', 'e'}; // (8) C++11 Initializer List ("=" optional) cout << str2 << endl; // "orange" // Using C-string literal is more convenient // Included in string class to make initializer list syntax universal } |
string Class Overloaded Operators
Most of the string class operators are overloaded to handle string
objects, as well as C-string and literals.
// Member functions - First operand must be a string object = // assignment [] // character at index - no index range check += // append // Friends (non-member functions) - First operand could be a non-string + // Concatenate two strings (one of them could be C-string or literal), // return a new string object (by value) ==, !=, <, <=, >, >= // Relational (comparison) operators. // Compare two strings (one of them could be C-string or literal) // based on the machine collating sequence >> // Stream extraction (input) << // Stream insertion (output)
Public Functions
Most of the string class functions are overloaded to handle string
objects, as well as C-string and literals.
// Capacity size_t size () const; // Return the size of the string size_t length () const; // same as above // length() was from earlier version, size() added for compatibility with STL bool empty () const; // Return true for empty string void clear (); // Clear to empty string void resize (size_t n, char pad = '\0'); // resize the string to length n, // discard trailing characters, or insert pad char string::npos // static variable for the maximum possible characters in string, // typically max of size_t (unsigned int) size_t max_size () const; // Return the maximum size of string object size_t capacity () const; // Storage (in terms of characters) currently allocated void reserve (size_t n = 0); // Request for minimum of this capacity void shrink_to_fit (); // (C++11) Request to reduce the capacity
Unlike C-string, which uses a fixed-size array, the string
class handles the memory allocated implicitly. In other words, you can append more characters without worrying about exceeding the size. C++ implementation may allocate an initial block which is larger than the actual string length to allow the content to grow, and allocate more block when the current block is filled. You can use function capacity()
to check the current allocation, and reserve()
to request for a minimum allocation.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <iostream> #include <string> // C++ string class using namespace std; int main() { string strLarge("This is a very very very vary large string"); string strSmall("Hi"); string strEmpty; cout << "size=" << strLarge.size() << " capacity=" << strLarge.capacity() << endl; cout << "size=" << strSmall.size() << " capacity=" << strSmall.capacity() << endl; cout << "size=" << strEmpty.size() << " capacity=" << strEmpty.capacity() << endl; cout << "string::npos=" << string::npos << endl; cout << "max_size=" << strEmpty.max_size() << endl; strSmall.reserve(100); cout << "size=" << strSmall.size() << " capacity=" << strSmall.capacity() << endl; strLarge.resize(10); cout << strLarge << endl; cout << "size=" << strLarge.size() << " capacity=" << strLarge.capacity() << endl; strSmall.resize(10, '-'); cout << strSmall << endl; cout << "size=" << strSmall.size() << " capacity=" << strSmall.capacity() << endl; strLarge.clear(); cout << "size=" << strLarge.size() << " capacity=" << strLarge.capacity() << endl; strLarge.shrink_to_fit(); // C++11 cout << "size=" << strLarge.size() << " capacity=" << strLarge.capacity() << endl; } |
size=42 capacity=42 size=2 capacity=2 size=0 capacity=0 string::npos=4294967295 max_size=1073741820 size=2 capacity=100 This is a size=10 capacity=42 Hi-------- size=10 capacity=100 size=0 capacity=42 size=0 capacity=0
// C-string
c_str;
Some functions, such as ofstream
's open()
which opens a file, accept only C-string. You can use c_str
to get a C-string from an string
object.
// Element Access char & operator[] (size_t pos); // Return char at pos, no index range check char & at (size_t pos); // Return char at pos, with index range check char & front (); // Return first char char & back (); // Return last char string substr (size_t pos = 0, size_t len = npos) const; // Return a substring // Modifying append insert assign erase replace swap push_back pop_back compare // Searching size_t find (const string & str, size_t pos = 0) const; size_t find (const char * cstr, size_t pos = 0) const; size_t find (const char * cstr, size_t pos, size_t n) const; size_t find (char c, size_t pos = 0) const; // Find the first occurrence of the string or char, starting from pos // Return the index or string::npos if not found rfind: last occurrence find_first_of: first occurrence of ANY of the character in the string find_last_of: last occurrence of ANY of the character in the string find_first_not_of: first occurrence of NOT ANY of the character in the string find_last_not_of: last occurrence of NOT ANY of the character in the string
Example: string objects and their operations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
/* * Guess a secret word (WordGuess.cpp) */ #include <iostream> #include <string> #include <cstdlib> #include <ctime> #include <cctype> using namespace std; const int NUM_WORDS = 18; const string WORD_LIST[NUM_WORDS] = { "apple", "orange", "banana", "watermelon", "pear", "pineapple", "papaya", "mango", "grape", "strawberry", "lemon", "peach", "cherry", "apricot", "coconut", "honeydew", "apricot", "blueberry"}; int main() { // Seed the pseudo-random number generator srand(time(0)); bool over = false; // gameover do { string target = WORD_LIST[rand() % NUM_WORDS]; // choose a word between 0 to NUM_WORDS-1 int target_length = target.length(); string attempt(target_length, '-'); // init to all dashes string badChars; // contains bad chars used int trial = 1; // number of trials cout << "Guess the secret word" << endl; while (attempt != target) { char letter; cout << "Your guess so far: " << attempt << endl; cout << "Trial " << trial << ": Guess a letter: "; cin >> letter; // Check if the letter has been used if (badChars.find(letter) != string::npos || attempt.find(letter) != string::npos) { cout << "You already use this letter. Try again.\n"; continue; } // Check for good or bad letter int pos = target.find(letter); if (pos == string::npos) { cout << "Oh, bad guess!\n"; badChars += letter; // add to badChars string } else { cout << "Good guess!\n"; attempt[pos] = letter; // Check if this letter appears again later do { pos = target.find(letter, pos + 1); if (pos != string::npos) attempt[pos] = letter; } while (pos != string::npos); } ++trial; } cout << "You got it in " << trial << " trials! The secret word is \"" << target << "\"" << endl; char playAgain; cout << "Another game? <y/n> "; cin >> playAgain; if (playAgain != 'y' && playAgain != 'Y') over = true; } while (!over); cout << "Bye\n"; return 0; } |
[TODO] More Example
Converting a string to Uppercase/Lowercase
Use the transform()
function in algorithm
.
#include <algorithm> #include <string> #include <cctype> std::string str = "Hello World"; std::transform(str.begin(), str.end(), str.begin(), ::toupper);
The C-String Input Methods
C-string has three input methods: stream extraction operator (>>
), getline()
and get()
. All 3 functions belong to the istream
class.
istream's Overloaded Stream Extraction Operator (>>)
The stream extraction operator (>>
) of istream
class has the following prototype for C-strings:
istream & operator>> (istream & is, char * str);
// Example usage:
char str[80];
cin >> str;
It extracts characters from the input stream and store into str
, until either a whitespace (blank, tab, newline) is encountered or width-1
characters is read. A terminating null character is automatically inserted. The default width
is 0, indicating unlimited. You can set the width
via cin >> setw(n)
(in header <iomanip>
) or cin.width(n)
. setw()
is non-sticky and is only applicable to next input operation. It is reset to 0. The trailing whitespace is left in the input stream. The leading white spaces are ignored.
For example,
const int SIZE = 5; char str[SIZE]; // max strlen is SIZE - 1 cout << "Enter a word: "; cin >> setw(SIZE) >> str; // need <iomanip> header cout << str << endl;
We set the width
to the SIZE
(=5) of the char[]
. cin <<
reads up to 4 characters or whitespace.
- If you enter
"12\n"
,"12"
is read intostr
, and"\n"
remains in the input buffer. - If you enter
"12345\n"
,"1234"
is read intostr
, and"5\n"
remains in the input buffer. - If you enter
"12 345\n"
,"12"
is read intostr
, and" 345\n"
remains in the input buffer. - The next
cin >>
discards the leading whitespaces and starts with the first non-whitespace character. - If
width
is not set properly and if the input (including the terminating null character) exceeds the size ofchar
array, memory will be corrupted. - You may need to flush the input buffer (see below).
istream::getline()
The getline()
function of the istream
class has the following prototypes:
istream & getline (char * str, int n); istream & getline (char * str, int n, char delim); // Example usage char str[80]; cin.getline(str, 80); // Read up to 79 chars or '\n'; discarding '\n' cin.getline(str, 80, ':'); // Read up to 79 chars or ':'; discarding ':'
getline()
extracts characters from the input stream and stores in str
, until either it reaches the delimiter character (default of '\n'
), or n-1
character is written to str
. A terminating null character is automatically inserted. The delimiter, if found, is extracted and discarded from input stream. You can use cin.gcount()
to get the number of characters extracted (including delim
). getline()
reads all whitespace (including leading whitespaces which is ignore by cin >>
).
If n-1
character is read and the next character is not delimit, then the failbit
(of the istream
) is set. You can check the failbit
via bool
function cin.fail()
. You need to invoke cin.clear()
to clear the error bit. Otherwise, all subsequent getline()
will fail and return gcount()
of 0.
For example,
const int SIZE = 5; char str[SIZE]; // max strlen is SIZE - 1 cout << "Enter a line: "; cin.getline(str, SIZE); // Read a line (including whitespaces) until newline, discard newline cout << "\"" << str << "\" length=" << strlen(str) << endl; cout << "Number of characters extracted: " << cin.gcount() << endl; if (cin.fail()) { cout << "failbit is set!" << endl; cin.clear(); // Clear all error bits. Otherwise, subsequent getline() fails }
Again, we set n
to the SIZE
(=5) of char[]
. getline()
reads up to 4 characters or '\n'
.
- If you enter
"xxxx\n"
, wherexxxx
may include whitespaces,"xxxx"
is read intostr
, and"\n"
discarded from input buffer. - If you enter
"xxxxyyy\n"
,"xxxx"
is read into str,"yyy\n"
remains in input buffer.failbit
is set. You need to clear the error bits before issuing anothergetline()
call.
istream::get()
The get()
function of the istream
class has the following prototypes for C-string:
// C-string
istream & get (char * str, int n);
istream & get (char * str, int n, char delim);
get(str, n, delim)
is similar to getline(str, n, delim)
, except that the delim
character is not extracted and remains in the input stream.
Single-character Input
The get()
member function is more often used to read a single character, unformatted, including whitespaces and newlines. It has the following two versions:
// Single character istream & get (char & c); // Read next character into the char reference and // return the istream for concatenated operations // It returns null pointer (converted to false) at end-of-file int get (); // Read next character and return an int // Return a special value EOF at end-of-file // Examples char ch; while (cin.get(ch) && ch != '\') { ...... } // read all characters until newline // You cannot use cin >> ch, because it ignores the whitespace while (cin.get(ch)) { ...... } // read until end-of-file int ch; while (ch = cin.get() != EOF) { ....... } // read until end-of-file
When the end-of-file is encountered, get(char &)
returns a null pointer, which is converted to false
. On the other hand, get(void)
return a special value EOF (defined in <iostream>
). get(char &)
has no room to represent any special symbol such as EOF!
In brief, there are 3 methods for reading single character, cin >> char
, get(char &)
and get(void)
. cin >> char
skips whitespaces, get(char &)
reads a character by reference, while get(void)
reads a character and return an int
. get(void)
is closely resembled the C's getchar(void)
function (in stdio.h
) and can be used to convert C programs into C++.
Flushing the cin Buffer
Use cin.ignore()
as follows. You may need to issue an cin.clear()
to clear the error bits first.
// Ignore to the end-of-file cin.ignore(numeric_limits<streamsize>::max()); // need header <limits> // Ignore to the end-of-line cin.ignore(numeric_limits<streamsize>::max(), '\n');
Others
istream::peek()
, istream::unget()
, etc.
The string Class Input Methods
The string
class has two input methods: stream extraction operator (>>
) and getline()
. Both methods are similar to C-string counterpart, but they are much simpler, as you don't need to worry about the limit of the string
, compared with a fixed-size char
array.
string's Stream Extraction Operator (>>)
The string
class overloads the >>
(stream extraction operator) via friend function such that it operates on string
object like C-string:
istream & operator>> (istream & is, string & str) // Example usage string str; cin >> str; // Compared with C-string, no need to set the width
It extracts a string (word) from the input stream, delimited by whitespace (blank, tab or newline), and stores in str
, overriding its previous value. The size of str
is determined by the length of input.
string::getline()
The string
class also provides a friend function getline()
:
istream & getline (istream & is, string & str); istream & getline (istream & is, string & str, char delim); // Example usage string str; getline(cin, str); // default delimiter of '\n' getline(cin, str, ':'); // Compared with C-string: // 1. No need to specify a limit // 2. NOT cin.getline() // C-string getline() is a member function of istream class // string class' getline() is a non-member friend function
It extracts characters from the input stream into str
until the delimiter character is found (default of newline '\n'
) or end-of-file is reached. The delimiter is extracted and discard from the input buffer, i.e., the next operation will begin after the delimiter. The size of str
is determined by the length of input.
Notes
- The maximum allowable size for a
string
object is defined by the constantstring::npos
, which is typically the maximum value ofunsigned int
. - If
getline()
is used to read from a file, and end-of-file is encountered, theeofbit
of the input stream will be set. That is,fail()
andeof()
of the input stream will returntrue
. - If the maximum allowable size of string is reached, or memory exhausted, the
failbit
of the input stream will be set. That is,fail()
of the input stream will returntrue
. - An input stream maintains its status in these bits:
goodbit
(good()
function) indicates all is fine;failbit
(fail()
function) indicates input error;badbit
(bad()
function) indicates recognized failure such as hardware failure;eofbit
(eof()
function) indicates end-of-file detected.
basic_string Template Class
The string
class is an instantiation of the basic_string
template class with parameterized type of char
.
The declaration of basic_string
is:
template < class charT, class traits = char_traits<charT>, // basic_string::traits_type class Alloc = allocator<charT> > // basic_string::allocator_type class basic_string;
There are 4 instantiations for basic_string
template class, with a typedef
.
typedef basic_string<char> string; typedef basic_string<wchar_t> wstring; typedef basic_string<char16_t> u16string; // C++11 typedef basic_string<char32_t> u32string; // C++11
Unicode Characters and Strings
[TODO] Types: wchar_t
, char16_t
, char32_t
.
[TODO] C's headers: cuchar
, wchar
, cwctype
.
[TODO] C++ Classes: wstring
, u16string
, u32string
.