Strings
Strings are part of the C/C++ Standard Library. In the original ANSI Standard C
developed by Brian Kernighan and Dennis Ritchie "strings" were implemented as
character arrays using the null terminator ('\0') to mark the end of a string.

In order to have addess to all of the string functions of ANSI Standard C you
must...
#include <string.h> // Gets only the ANSI standard C functions
Most used functions from ANSI Standard C
-
char *strcpy(s,ct) Copy string ct to string s, adding the
'\0'. Return s.
-
char *strcat(s,ct) Concatenate string ct to end of string s. Return s.
-
int strcmp(cs,ct) Compare string cs to string ct. Return <0 if
cs<ct, 0 if cs==ct, or >0 if cs>ct.
-
char *strncpy(s,ct,n) Copy at most n characters of ct to s.
Return s.
-
char *strncat(s,ct,n) Concatenate at most n characters of ct to the
end of s. Return s.
-
int strncmp(s,ct,n) Compare at most n characters of string cs to string ct.
Return <0 if cs<ct, 0 if cs==ct, or >0 if cs>ct
-
char *strchr(cs,c) Return pointer to first occurance of c in cs or
NULL if not present.
-
char *strrchr(cs,c) Return pointer to last occurance of c in cs or
NULL if not present.
-
char *strstr(cs,ct) Return pointer to first occurance of string ct in cs, or
NULL if not present.
-
size_t strlen(cs) Returns length of cs as an integer.
-
char *strtok(s,ct) Returns a token split from s using delimiters in ct.
This is a parser. See the example in the code below.
Sample Code
#include <cstring>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
char str1[64];
char str2[32] = " With a demo of strcat().";
// DEMONSTRATION 1: strcpy and strncpy
strcpy(str1, "This is a test string.");
cout << "\t str1 = " << str1 << endl << endl;
// Copy a string into str1 using strncpy
strncpy(str1, "ABCDEFGHIJ", 5);
cout << "\t str1 = " << str1 << endl << endl;
cout << "Note that strncpy just overwrote the first 5 characters of str1\n";
cout << " which were \"ABCDE\" without adding a NULL terminator, thus\n";
cout << " we see the rest of the old string still there so use with caution.\n\n";
cout << "--------------------------------------------------------------\n\n";
// DEMONSTRATION 2: strcat and strncat
strcpy(str1, "This is a test string.");
strcat(str1, str2);
cout << "\t str1 = " << str1 << endl << endl;
strcpy(str1, "This is a test string.");
cout << "Calling strncat(str1, str2, 12);\n\n";
strncat(str1, str2, 12);
cout << "\t str1 = " << str1 << endl << endl;
cout << "--------------------------------------------------------------\n\n";
// DEMONSTRATION 3: strcmp and strncmp
strcpy(str1, "ABCD");
strcpy(str2, "EFGH");
cout << "\t Calling strcmp(str1, str2) = " << strcmp(str1, str2) << endl;
cout << "\t Calling strcmp(str2, str1) = " << strcmp(str2, str1) << endl << endl;
strcpy(str2, "ABCD");
cout << "\t Calling strcmp(str1, str2) = " << strcmp(str1, str2) << endl << endl;
strcpy(str1, "ABCD");
strcpy(str2, "ABGH");
cout << "\t Calling strncmp(str1, str2, 3) = " << strncmp(str1, str2, 3) << endl;
cout << "\t Calling strncmp(str2, str1, 3) = " << strncmp(str2, str1, 3) << endl;
cout << "\t Calling strncmp(str1, str2, 2) = " << strncmp(str1, str2, 2) << endl << endl;
cout << "--------------------------------------------------------------\n\n";
// DEMONSTRATION 4: strchr, strrchr, strstr, and strlen
// Reset str1 back to original string for next demos
strcpy(str1, "This is a test string.");
// Demo strchr
cout << "\t Calling strchr(str1, 's') = " << strchr(str1, 's') << endl << endl;
cout << "Note that the returned value is a pointer to the first occurance of 's'\n";
cout << " in str1. When this returned pointer is passed to cout everything in the\n";
cout << " string from that pointer to the null terminator is printed.\n\n";
cout << "--------------------------------------------------------------\n\n";
// Demo strrchr
cout << "\t Calling strrchr(str1, 's') = " << strrchr(str1, 's') << endl << endl;
cout << "Note that the returned value is a pointer to the last occurance of 's'\n";
cout << " in str1. When this returned pointer is passed to cout everything in the\n";
cout << " string from that pointer to the null terminator is printed.\n\n";
cout << "--------------------------------------------------------------\n\n";
// Demo strstr
cout << "\t Calling strstr(str1, \"test\") = " << strstr(str1, "test") << endl << endl;
cout << "Note that the returned value is a pointer to the first occurance of \"test\"\n";
cout << " in str1. When this returned pointer is passed to cout everything in the\n";
cout << " string from that pointer to the null terminator is printed.\n\n";
cout << "--------------------------------------------------------------\n\n";
// Demo strlen
cout << "\t Calling strlen(str1) = " << strlen(str1) << endl;
cout << "--------------------------------------------------------------\n\n";
// DEMONSTRATION 5: strtok
strcpy(str1, "This is a test string");
char *tok;
cout << "Making initial call to strtok(str1, \" .,;:\"); with str1=\"This is a test string.\"\n";
tok = strtok(str1, " .,;:");
cout << "\t Calling strtok(str1, \" .,;:\") = " << tok << endl << endl;
cout << "Subsequent calls to strtok give:\n";
while((tok = strtok(NULL, " .,;:")) != NULL)
{
if(tok != NULL)
cout << "\t Calling strtok(NULL, \" .,;:\") = " << tok << endl;
}
return 0;
}
NOTE: If you #include <cstring> or #include <string> then there are also functions to handle
Unicode strings (2 byte chars). While these are not used much now they may become a standard in the
future if programs become more "internationalized".
The C++ string template
Calling this a template is perhaps a misnomer as this implies an ADT with a generic data type. The
string template is for use almost exclusively with the char data type, though
there are portions of it that can handle the wchar (wide char) data type for Unicode strings.
In order to have addess to all of the string functions of ANSI Standard C++ you
must...
#include <string>
Do not use <cstring> or you won’t get all the C++ functionality of the string template.
Constructors
-
Default constructor
string s1;
s1 = "Test string 1";
-
Initializer constructor
string s2("Test string 2");
-
Dynamic creation of a string using default constructor
string *sptr1 = new string();
*sptr1 = "Test string 3";
-
Dynamic creation of a string using initializer constructor
string *sptr2 = new string("testing2");
Overloaded Operators
The following operators have been overloaded in the string template:
-
Equivalence operator: =
-
Input/Output operators: <<, >>
You can also use getline(cin, str) for input.
-
Logical operators: ==, !=, <, >, <=, >=
-
Array operator: []
Functions
These abbreviations are used in the following function prototypes:
-
npos = last position in the string
-
str = another string
-
pos = position (index)
-
n = number of characters to act on
Changing the contents of a string
-
string& append(const string& str); Appends str to the end of the string.
-
string& append(const string& str, long pos, long n); Appends n characters in
str starting at index pos to the end of the string.
-
string& assign(const string& str); Works like the = operator. Replaces
the current contents of the string with str. Returns a reference to the same string.
-
string& erase(long p0 = 0, long n = npos); Delete from the string npos characters
starting at index p0.
-
iterator erase(iterator it); Delete from the string the character referenced by the
iterator. Return an iterator to the first character after the one deleted.
-
iterator erase(iterator first, iterator last); Delete from the string all characters
starting from iterator first up to but not including the character referenced by
iterator last. Return an iterator to the first character after the last one deleted.
Which should be the same as iterator last.
-
string& insert(long p0, const string& str); Insert string str into the string just
before index p0. Returns a reference to this string.
-
string& insert(long p0, const string& str, long pos, long n); Insert n characters
from string str starting at index pos into the string just before index p0.
Returns a reference to this string.
-
void insert(iterator it, const_iterator first, const_iterator last); Insert into this
string starting at the position referenced by iterator it the characters from another
string starting at its iterator first going up to but not including its iterator last.
-
string& replace(long p0, long n0, const basic_string& str); Replace up to n0
characters in the string starting at index p0 with characters from str.
Return a reference to this string.
-
string& replace(long p0, long n0, const string& str, long pos, long n); Replace up to
n0 characters in the string starting at index p0 with up to n characters
starting at index pos from str. Return a reference to this string.
Getting size information on a string
-
long length() const; Returns number of characters in the string.
-
long size() const; Returns number of characters in the string. Same as length().
-
long max_size() const; Returns maximum size the string can be which may be the entire heap.
-
long capacity() const; Returns the size of memory allocated for the string.
Minimum value will be what is returned by size().
-
bool empty() const; Returns true if the string is empty.
Comparing two strings
-
int compare(const string& str) const; Returns a negative value if the string
alphabetically comes before str; 0 if the two are identical, or a positive value
if the string alphabetically comes after str.
-
int compare(long p0, long n0, const string& str); Works same as the first compare
but starts at position p0 in the string and compares up to n0 characters.
-
int compare(long p0, long n0, const string& str, long pos, long n); Works same as
second compare but starts at position pos in str and compares up to
n characters.
Find something in the string
-
long find(const string&str, long pos = 0) const; Return the index
in the string of the first occurance of str starting from position pos.
-
long rfind(const string& str, long pos = npos) const; Return the index in the
string of the last occurance of str starting from position npos.
-
long find_first_of(const string& str, long pos = 0) const; Return the index of
the first occurrence of any character in str in the string starting from position pos.
-
long find_last_of(const string& str, long pos = npos) const; Return the index of
the first occurrence of any character in str in the string starting from position
npos and searching backward.
-
long find_first_not_of(const string& str, long pos = 0) const; Return the index
of the first occurrence of any character NOT in str in the string starting from
position pos.
-
long find_last_not_of(const string& str, long pos = npos) const; Return the index
of the first occurrence of any character NOT in str in the string starting from
position npos and searching backward.
Getting a substring of the string
-
string substr(long pos = 0, long n = npos) const; Return a new string that is
a copy of n characters starting at index pos in this string.
Getting a char array equivalent of the string
-
const char *c_str() const; Return a pointer to a character array holding
the equivalent of the contents of this string. Be careful because this may not be
persistent. The safe thing to do is copy it immediately into another character array.
Strings and Iterators
-
iterator begin(); Returns an iterator referencing the first character in the
string. If the string is empty it returns the same reference as end(). The iterator
is a forward iterator.
-
iterator end(); Returns an iterator referencing just beyond the end of the
string. The iterator is a forward iterator.
-
reverse_iterator rbegin(); Returns an iterator referencing the end of the
string. The iterator is a reverse iterator.
-
reverse_iterator rend(); Returns an iterator referencing just before the first
character in the string. The iterator is a reverse iterator.
Warning: You must increment a reverse_iterator to go backward through a string (rItr ++).
Do not decrement it (rItr--).
Sample Code
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
char dummy[32];
// Demonstrate static and dynamic use of string constructors
cout << " Demonstration of string constructors\n";
// Default constructor
string s1;
s1 = "Test string 1";
cout << "\nResult: s1 = " << s1 << endl << endl;
// Iniitializer constructor
string s2("Test string 2");
cout << "\nResult: s2 = " << s2 << endl << endl;
// Dynamic creation of a string using default constructor
string *sptr1 = new string();
*sptr1 = "Test string 3";
cout << "\nResult: *sptr1 = " << *sptr1 << endl << endl;
// Dynamic creation of a string using init constructor
string *sptr2 = new string("Test string 4");
cout << "\nResult: *sptr2 = " << *sptr2 << endl << endl;
cout << "====================================================================\n";
// Demonstrate input (cin) and output (cout) of strings
cout << "Demonstration of overloaded << (for cout) and >> (for cin) operators\n";
string s3;
cout << "Enter a string (no spaces) then press Enter\n\n";
cin >> ws; // Clear the buffer
cin >> s3;
cout << "\nYou entered the string: " << s3 << endl << endl;
cout << "Demonstration of using getline with strings\n";
cout << "Enter a string with spaces then press Enter\n\n";
cin >> ws; // Clear the buffer
getline(cin, s3);
// What about cin.getline(s3, '\n'); This only works with character arrays not with string
cout << "\nYou entered the string: " << s3 << endl << endl;
cout << "-------------------------------------------------------------------\n";
// Demonstrate overloaded logical operators with strings
cout << " Demonstration of overloaded logical operators with strings\n";
s1 = "Test string";
s2 = "Test string";
if(s1 == s2)
cout << "Strings are equal\n";
else
cout << "Strings are not equal\n\n";
cout << "-------------------------------------------------------------------\n";
s1 = "Test string 1";
s2 = "Test string 2";
if(s1 != s2)
cout << "Strings are not equal\n";
else
cout << "Strings are equal\n\n";
cout << "-------------------------------------------------------------------\n";
if(s1 < s2)
cout << "String s1 is less than s2\n";
else
cout << "String s1 is greater than or equal to s2\n\n";
cout << "-------------------------------------------------------------------\n";
if(s2 > s1)
cout << "String s2 is greater than s1\n";
else
cout << "String s2 is less than or equal to s1\n\n";
cout << "-------------------------------------------------------------------\n";
// Operators <=, >= have also been overloaded but are not shown here.
// Demonstrate overloaded logical operators with strings
cout << " Demonstration of overloaded [] operator with strings\n";
for(int i=0; i<(int)s1.length(); i++)
cout << s1[i] << " ";
cout << endl << endl;
cout << "====================================================================\n";
// Demonstrate functions to change the contents of strings
s1 = "Test string 1";
s2 = "Test string 2";
cout << " Demonstration of changing the contents of a string\n";
cout << "Executing code demonstrating append:\n\n";
s1.append(" With this appended to it.");
s2.append(" With this appended to it.", 5, 14);
cout << "\nResults: \n";
cout << "\n\ts1 = " << s1 << endl;
cout << "\n\ts2 = " << s2 << endl;
cout << "-------------------------------------------------------------------\n\n";
cout << "Executing code demonstrating assign:\n\n";
s1.assign("Test string 1");
s2.assign("Test string 2");
cout << "\nResults: \n";
cout << "\n\ts1 = " << s1 << endl;
cout << "\n\ts2 = " << s2 << endl;
cout << "-------------------------------------------------------------------\n\n";
s3 = "Test string 3";
cout << "Executing code demonstrating erase:\n\n";
s1.erase(5, 5);
string::iterator itr = s2.begin();
itr+=4; // Set iterator to first space
s2.erase(itr);
string::iterator itrB = s3.begin();
itrB+=5;
string::iterator itrE = s3.begin();
itrE+=12;
s3.erase(itrB, itrE);
cout << "\nResults: \n";
cout << "\n\ts1 = " << s1 << endl;
cout << "\n\ts2 = " << s2 << endl;
cout << "\n\ts3 = " << s3 << endl;
cout << "-------------------------------------------------------------------\n\n";
s1 = "Test string 1";
s2 = "Test string 2";
s3 = "Test string 3";
string s4 = "Test string 4";
cout << "Executing code demonstrating insert:\n\n";
s1.insert(4, "ing");
s2.insert(4, "Ring Ring, anyone there?", 1, 3);
itr = s3.begin();
itrB = s4.begin();
itrE = s4.begin();
itrE+=5;
s3.insert(itr, itrB, itrE);
cout << "\nResults: \n";
cout << "\n\ts1 = " << s1 << endl;
cout << "\n\ts2 = " << s2 << endl;
cout << "\n\ts3 = " << s3 << endl;
cout << "-------------------------------------------------------------------\n\n";
s1 = "Test string 1";
s2 = "Test string 2";
cout << "Executing code demonstrating replace:\n\n";
s1.replace(0, 4, "What a fun time");
s2.replace(0, 4, "What a fun time", 0, 10);
cout << "\nResults: \n";
cout << "\n\ts1 = " << s1 << endl;
cout << "\n\ts2 = " << s2 << endl;
cout << "====================================================================\n";
cout << " Demonstration of getting size information on a string\n";
s1 = "Test string 1";
cout << "\nResults: \n";
cout << "\tlength = " << s1.length() << endl;
cout << "\tsize = " << s1.size() << endl;
cout << "\tmax_size = " << s1.max_size() << endl;
cout << "\tcapacity = " << s1.capacity() << endl;
cout << "\tempty = " << s1.empty() << endl;
cout << "====================================================================\n";
cout << " Demonstration of comparing two strings\n";
s1 = "Test string 2 this isn't";
s2 = "Test string 2";
cout << "\nResults: \n";
cout << "\ts1.compare(s2) = " << s1.compare(s2) << endl;
cout << "\ts1.compare(0, 13, s2) = " << s1.compare(0, 13, s2) << endl;
cout << "\ts1.compare(6, 6, s2, 6, 6) = " << s1.compare(6, 6, s2, 6, 6) << endl;
cout << "====================================================================\n";
cout << " Demonstration of searching a string\n";
s1 = "Test string 1";
cout << "\ts1.find(\"string\", 0) = " << s1.find("string", 0) << endl;
cout << "\ts1.rfind(\"string\", s1.length()) = " << s1.rfind("string", s1.length()) << endl;
cout << "\ts1.find_first_of(\"abcde\", 0) = " << s1.find_first_of("abcde", 0) << endl;
cout << "\ts1.find_last_of(\"abcde\", s1.length()) = " << s1.find_last_of("abcde", s1.length()) << endl;
cout << "\ts1.find_first_not_of(\"abcde\", 0) = " << s1.find_first_not_of("abcde", 0) << endl;
cout << "\ts1.find_last_not_of(\"abcde\", s1.length()) = " << s1.find_last_not_of("abcde", s1.length()) << endl;
cout << "====================================================================\n";
cout << " Demonstration of getting a substring and a \n";
cout << " character array representing a string\n";
cout << "\ts1.substr(5) = " << s1.substr(5) << endl;
cout << "\ts1.substr(5, 6) = " << s1.substr(5, 6) << endl;
cout << "\ts1.c_str() = " << s1.c_str() << endl;
cout << "====================================================================\n";
cout << " Demonstration of forward and reverse iterators in a string. \n";
for(string::iterator it=s1.begin(); it != s1.end(); it++)
cout << *it << " ";
cout << endl << endl << "\t";
for(string::reverse_iterator it=s1.rbegin(); it != s1.rend(); it++)
cout << *it << " ";
cout << endl << endl;
return 0;
}