0% found this document useful (0 votes)
28 views

Strings - The Basics

Strings in C++ allow for easier processing of textual data compared to single characters. A string is a set of characters that is treated as a whole. The std::string header must be included to use strings. Strings can be initialized using assignment or a function-like syntax. The + operator concatenates strings rather than adding them arithmetically. Various comparison operators like ==, >, < can be used to compare strings. Substrings of a string can be extracted using the substr member function by specifying a starting position and length.

Uploaded by

pazov44
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views

Strings - The Basics

Strings in C++ allow for easier processing of textual data compared to single characters. A string is a set of characters that is treated as a whole. The std::string header must be included to use strings. Strings can be initialized using assignment or a function-like syntax. The + operator concatenates strings rather than adding them arithmetically. Various comparison operators like ==, >, < can be used to compare strings. Substrings of a string can be extracted using the substr member function by specifying a starting position and length.

Uploaded by

pazov44
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 51

Strings – the basics

Chapter 4 C++Institute
What is a string?

 A string (in the C++ language sense) is not a cord or a ribbon, but a set of characters. You
might ask what we can use it for if we have a data type like char. That's a good question.
 The char variables are useful (and generally all we need) when we want to process single
characters, but they’re extremely difficult when we have to deal with data containing all
kinds of names (e.g. surnames, city names, street names, etc) or just text (e.g. agreements,
statements or simply books or emails). Processing that kind of data as a set of chars
resembles spelling – it’s tedious and slow. It’s much easier to treat all characters as a
whole, stored, assigned and processed at the same time.
What is a string?

 Note one very important fact: the string type is not a built-in type (like int which can be
used at any time with no special preparation). If we want to use strings in our code, we
have to put the #include directive at the top of our program and request a header file
named string to be included during the compilation.
 This lack of directive will cause a compilation error. Remember – you’ve been warned.
Initializing a string

 A string can be initialized in a way that is identical to the one used for other regular types
i.e. by using an assignment operator followed by a string literal (a set of characters
surrounded by double quotes). But don't forget: apostrophes are for character literals
only. Strings always use quotes.
Initializing a string

 In effect, the newly created variable named PetName will be assigned with a string
consisting of the characters “Lassie”. This isn’t the only information stored inside
the PetName variable, but we don't want to get ahead of the facts.
 Notice that sometimes we have to use the word string in two different meanings:

as a type name (as in a variable of type string) and

as an entity consisting of a finite number of characters.


Initializing a string

 We don't use the assignment operator here. We use a syntax that clearly resembles the
function invocation, with a pair of parentheses and an argument within. You may ask if
there’s a real function named PetName being invoked. The answer is “yes and no”. Yes
because there’s a specialized function responsible for creating strings and the function is
being invoked every time you want to create a new string. No because you're not allowed
to directly invoke the function like any other regular function.
Initializing a string

 You can also use a value stored in any string variable to initialize the newly declared
variable like in the example on the right →
 Both forms (assigning and functional) are permissable.
String operators
 Just like any other data type, the string type
has its own operators.

One of the most important and most


frequently used is the + operator.

Don't be misled – it doesn’t add strings in the


same way as traditional arithmetic addition.
Instead,
it concatenates strings (i.e. it glues them
together, giving a new string which has arisen
out of the values of its arguments).
String operators

 It may seem obvious, but it’s worth mentioning here:

the concatenating + is not commutative


(a + b aren’t always equal to b + a) in contrast to the adding +.

#include <iostream>
#include <string>

using namespace std;

int main(void) {
string TheGood = "Sun", TheBad = "Lune";
cout << TheGood + TheBad << endl;
cout << TheBad + TheGood << endl;
return 0;
}
String operators
 The + (concatenation) operator has one important limitation. It cannot concatenate
literals. It can concatenate any variable with a literal, a literal with a variable, and
obviously a variable with another variable, but concatenating literals is something the
operator will never do for us.

#include <iostream>
#include <string>

using namespace std;

int main(void) {
string String;
String = "A" + "B";
String = String + "C";
String = "B" + String;
cout << String << endl;
return 0;
}
String operators: + =

 We hope you aren’t surprised with the news that the + (concatenation) operator, just like its
arithmetic cousin, may be used as a short-cut operator.
Inputting strings
 Inputting strings is a bit more complicated, due to the fact that the cin stream treats spaces
(to be precise, not only regular spaces but also all so-called white characters) as
delimiters, demarcating limits between data. It means that you may run into trouble if you
want to input and store a string containing white characters.
Comparing strings

 Strings (just like any other data) may be compared. The simplest case occurs when you
want to check if two variables of type string contain identical strings.
 Something similar happens when you enter your password on logging into an account. The
password you entered is compared to the password stored in the system and if both strings
are equal, access is granted. (The real process is obviously more complex, but our
description is good enough to show you the idea of comparing strings).
Comparing strings
 If you want to check if two strings (i.e. variables of type string) contain the same string
(i.e. a chain of characters) you can use the old good == operator. It can answer your
question and satisfy your curiosity.
Comparing strings
 Of course, you can compare two
strings in more flexible ways too.
 All the operators designed to compare
data are at your disposal:
> < >= <= !=.
You can check if one of the strings is
greater/lesser than the other, but
remember that these comparisons are
carried out in alphabetical order
where 'a' is greater than 'A' (sic) and
obviously 'z' is greater than 'a', but
less obviously, 'a' is greater than '1'.
Comparing strings
- the objective approach

 Strings offer another more complex, but also more powerful, method of comparison. We
can make use of it if we have some background knowledge of how objects manipulate their
data. This’ll be a good introduction to practising the object-oriented programming style.
 In the classical approach, we usually have some data and a set of functions operating on
the data. We’re used to the following way of initiating data processing:

 function(data);
Comparing strings
- the objective approach

 In the object-oriented approach, we use slightly different terminology. Both the data and
the functions are embedded in the so-called object. The data is the
object's property or member variable, and the functions are the
object's methods or member functions.
We’ll return to these terms soon and explain their meaning in more detail.
 If we want a particular method (member function) to process data embedded within an
object, we activate the member function for the object. It looks like this:

 object.member_function();
Comparing strings
- the objective approach
Comparing strings
- the objective approach

 Of course, the possibilities of the compare member function don’t stop at checking the
identity of the strings. The function can also diagnose all of the possible relations between
two strings. Here’s how it works:

 str1.compare(str2) == 0 when str1 == str2


 str1.compare(str2) > 0 when str1 > str2
 str1.compare(str2) < 0 when str1 < str2

 Note, that the direction of the inequality is the same for both functional and objective
notations.
Comparing strings
- the objective approach
Substrings and more
Definition

 All string operations we’ve shown you thus far have referred to whole strings i.e. both
strings were taken integrally, from the first to the last character. The strings allow
themselves to be processed in a more precise way when only selected parts of them are
taken into consideration. A part of a string is called a substring.
 If we want to create a new string consisting of characters taken from another (or even the
same) string's substring, we can use a member function called substr, and its simplified,
informal prototype looks like this:

 newstr = oldstr.substr(substring_start_position, length_of_substring)


Substring “coordinates”
 The substring of any string is
defined by two “coordinates”:
 a place where the substring begins
(specified by
the substring_start_position param
eter) and its length (specified by
the length_of_substring parameter)
.
 Note that characters within a string
are numbered, and the first
character is that number 0.
Therefore, if a string
contains n characters, the last one
is the number n – 1.
Substring Parameters

 Both parameters have default values. This enables us to use the function in a more flexible way. So:
 s.substr(1,2) describes a substring of the s string, starting at its second character and ending at its
third character (inclusively)

 s.substr(1) describes a substring starting at the second character of the s string and containing all of
the remaining characters of s, including the last one; the omitted length_of_substring parameter
defaults to covering all the remaining characters in the s string

 s.substr() is just a copy of the whole s string

(the substring_start_position parameters defaults to 0)


The length of a string
 Every string has a length. Even an empty string (containing no characters at all) has a
length of zero. It's obvious that at some point we may want to know how long a particular
string is.
 This information is provided by two twin member functions. Their names are different, but
their behaviours are identical. We can say that these functions are synonyms.
 Their informal prototypes look like these:

int string_size = S.size();


int string_length = S.length();
The length of a string
 Both functions return a
value equal to the number
of all the characters
currently stored within a
string. Note that
the substr function returns a
string. This means that the
resulting string retains all its
original traits and therefore
has its own member functions
like substr or size.
 The program on the right,
although complicated, is
correct. Try to predict its
output.
More detailed string comparison

 Because we already know how to define and use substrings, we can take a little step back
and show you some other variants of the compare functions. They allow us not only to
compare whole strings, but also their substrings. Their prototypes are clear to understand
and easy to use (well, we hope you agree). Here are two of them (as usual, we give them to
you informally):

S.compare(substr_start, substr_length, other_string)


S.compare(substr_start, substr_length, other_string, other_substr_start, other_substr_length)
More detailed string comparison

 We’ll start with the first, obviously simpler case. This variant of the compare member
function compares the entire other string to the substring of the source string. This means
that the following snippet will output 0 (the strings are equal):

string S = "ABC";
cout << S.compare(1,1,"B");
More detailed string comparison

 The second variant allows us to use only a part of the other_string. Similarly, the following
snippet will also output 0:

string S = "ABC";
cout << S.compare(1,1,"ABC",1,1);
Finding strings inside strings

 Sometimes we have not only to extract a substring from a particular string, but also (which
is much more complex) to find a substring within another string, taking into account the
possibility that it may fail (not all haystacks contain needles).
 Strings can do this for us. They can search for a substring or for a single character. For this
purpose, we need to use one of the variants of the find member function. Two of them are
particularly useful:

int where_it_begins = S.find(another_string, start_here);


int where_it_is = S.find(any_character, start_here);
Finding strings inside strings
How big is the string actually?

 Every time we extend the string, e.g.


concatenating another string to it, the
new content is placed in the buffers.
If the buffers are large enough, then
extending the string doesn't require the
buffers to extend.
Of course, when the buffers are full
and the string is being extended again,
the buffers are reallocated to fit the
new content. This process is
fully transparent and in most cases,
you don't even need to know about it.
How can we control the size of the string?

 We can control the size of the memory a string uses with the reserve member function. It
can work in both directions with the same ease, i.e. it can shrink the buffers as well as
expand them. The function requires one parameter of type int to specify the desired size
of the allocated buffers.
 One important thing you need to know here: the content of the string isn't changed in any
way – we can say that the content is immune to the effect of the reserve function.
How can we control the size of the string?
How to control the content of the string

 We can also control the content length of the string in many ways. The functions we’re
going to show you here may also change the memory allocations – this is a possible side
effect.
 First of all, we can empty the string, completely removing all the characters currently
stored inside it. This is equivalent to assigning an empty string to the string, but it could
be a little bit faster.
 Emptying the string is done by the member function called clear.
It requires no parameters.
How to control the content of the string

 Changing the size of the string is carried out by the member function called resize. It's
basic variant requires one parameter of type int, specifying the desired new size of the
string. If the parameter is smaller than the current string size, the string will be truncated.
 If the parameter is larger than the string size, the string will be expanded. You can also use
an overloaded form of the function allowing you to specify a character to be used to fill the
newly allocated space (the null character '\0' is used for that purpose by default).
How to control the content of the string
How to control the content of the string

 Strings offer some convenient member functions to do this. We've said previously that
strings aren't arrays. Yes, it's still true, but they are able to present their content as if it
were an actual array.
 We can assume that it's a kind of very useful masquerade – a string can wear a mask and
show itself as an ordinary (well, almost ordinary) array. It allows us to read and write
every character separately.
How to control the content of the string
Strings – temporary summation
Appending a (sub)string

 One of the functions we’re going


to introduce here is append. This
name speaks for itself – it’s
designed to append one string to
another. If you’re an attentive
student, you've probably noticed
that the same task can be
performed by the += operator and
you may be wondering why we
need another tool for the same
task.
Appending a character

 If you want to append just one


character to a string, you can do
it by using the append function,
but there’s a more efficient way,
by using the push_back member
function. The example on the
right is more meaningful than
any description we can give you,
so here it is.
Inserting a (sub)string or a character

 Inserting a string into a string is like distending its contents from within. A new set of
contents is just “pushed” into the old one. For example: the following snippet of code will
print “to be or not to be” to the cout stream:

string quote = "to be ";

quote.append(quote);

quote.insert(6, "or not ");

cout << quote << endl;


Inserting a (sub)string or a character
 As you’ve probably guessed, the first
parameter specifies where the
insertion should be, while the second
says what should be inserted there.
This is only one among various
possibilities offered by the function.
Another member function can insert a
substring of a specified string in a way
very similar to the append function.
 There’s also a function that can insert a
single character, optionally duplicated
more than once. Both these functions
are put to work in the following
example →
Assigning a (sub)string or a character
 The assign member function does a job
which is very similar to the insert’s job,
but does not retain the previous string
content, and instead just replaces it with a
new one. You might ask why on earth
we’d want to use the assign function when
the exact same task can be performed by
the = operator.
 Well it’s not that simple. The assign is as
universal as the insert or append functions
and so is more convenient in some specific
applications.
Replacing a (sub)string

 Replacing a (sub)string with another (sub)string

 The replace member function is more subtle. It can replace a part of the string with
another string or another string’s substring.
 The function needs to know which part of the string it’s going to replace and you have to
specify this by delivering two numbers: the first describing the starting position and the
second saying how many characters will be replaced.
Replacing a (sub)string
 The first overloaded function
needs a string (as a third
parameter) to replace the old
content (it may be either
longer or shorter or equal in
size in comparison to the
original). The second function
enables you to specify the
substring to be used as a
substitution.
 The second variant of the
function is here on the right

Erasing a (sub)string

 We can also remove a part of a string, making the string shorter than before. We can do
this by using a member function called erase (a name which leaves no room for doubt) and
the function requires two numbers in order to perform its duty: the place where the
substring to be removed starts (this value defaults to zero) and the length of the substring
(this value defaults to the original string’s length).
This means that an invocation like this

TheString.erase();

erases all the characters from the string and leaves it empty.
Erasing a (sub)string
Exchanging the contents of two strings

 When we’re dealing with sorting, we have to be able to exchange the content of two
selected cells of an array. We have to have an auxiliary variable for that purpose, since the
operation resembles replacing the liquid content of two glasses – you can’t do this
successfully without using a third glass. So, if we want to replace a string (or a drink)
stored within Glass1 and Glass2 variables, we need a third variable (glass) to do it. This is
how it goes:

AGlass = Glass1;
Glass1 = Glass2;
Glass2 = AGlass;
Exchanging the contents of two strings

You might also like