STRINGS IN C++
Lesson Content: Strings in C++
Welcome to the lesson dedicated to strings in C++! In this lesson, we will explain in detail what strings are, how to use them, as well as their advantages and disadvantages. You will become familiar with the basic concepts, methods for manipulating strings, conversion between C++ strings and C-style arrays, and techniques for dynamic memory allocation for working with text. We will also cover modern techniques such as the use of std::string and advanced text processing functions.
Introduction to Strings in C++
Strings in C++ represent sequences of characters that are used to store and manipulate textual data. There are two main approaches to working with strings in C++:
-
C-style strings: These are arrays of characters terminated by a null character (
'\0'
). Although traditionally used, C-style strings require manual memory management and can be prone to errors such as buffer overflow and improper string termination handling. -
C++ string (std::string): This is a class from the C++ standard library (header
<string>
) that allows for safer and more intuitive string handling. std::string automatically manages memory, offers a rich set of functions for text manipulation (such as concatenation, comparison, searching, and modification), and integrates with other components of the standard library.
In modern C++ programming, it is recommended to use std::string instead of traditional C-style strings due to increased safety, easier code maintenance, and richer text manipulation capabilities.
This lesson will introduce you to the basic operations on strings, demonstrate how to create, modify, and compare strings, and highlight best practices for working with textual data in C++.
Data Type char in C++
The char data type is used to store individual characters and represents an integer type that occupies 8 bits of memory. Essentially, char holds the numeric value (most commonly the ASCII code) of a character, which allows for easy conversion between numeric and symbolic values.
Below is an example demonstrating the basic use of the char type – how a character is stored and then its numeric value, along with the character itself, is printed using the printf function.
// Example of using the char type
char c = 'A';
printf("%d, %c", c, c);
// The output will be: 65, A
In this example, the char variable c is initialized with the character 'A'. The printf function uses the format specifier "%d" to print the integer value (ASCII code) and "%c" to print the character itself. As a result, the output is: 65, A, where the number 65 represents the numeric value of the character 'A'.
It is actually an integer type that occupies 8 bits of memory. It is mainly used for storing character codes.
char c = 'A';
printf("%d, %c", c, c);
The output will be: 65 A.
First, the integer representing the character code of 'A' is displayed, followed by the character itself. The format specifier "%d" is used for printing the integer value, while "%c" is used for displaying the character.
C-style string
It originated in the C language and continues to be supported in C++. This string is actually a one-dimensional array of characters, terminated by a null character '\0'.
It can also be declared in the following way:
|
|
Text data in C++
In C++, there is a string data type that holds text. It is used like any other data type, and a variable of type string is declared in the following way. In fact, it represents an object of the string class.
// Importing the standard namespace
using namespace std;
string s = "This is some text.";
// Explicitly using the std namespace
std::string s = "This is some text.";
Inputting strings from standard input
To read a string up to a space, the cin command from the iostream library is used.
To print a string to the screen, the cout command from the iostream library is used.
Code example:
#include <iostream>
#include <string>
int main(){
string firstName, lastName;
cin >> firstName >> lastName;
cout << firstName << " " << lastName << endl;
return 0;
}
Entering a complete line of text from the keyboard
getline( cin,text);
The first argument of the getline function is cin, which specifies where the text is coming from (in this case, from the console, i.e., the keyboard).
The second argument is the name of the string variable where you want to store the entered text.
The getline function reads an entire line until the user presses [Enter]. This is useful when the input string contains spaces.
The getline function is part of the standard <string> header, so it needs to be included using the include directive:
Splitting words from text entered from the keyboard
To read a line of text, we can use the getline() function. However, if we use the variant of this function with a third parameter, which serves as a delimiter, and set it to a space character, we can immediately extract words from the text in the following way:
int main()
{
string word="";
int n = 0; // loop counter
getline(cin, text);// Reads a line of text and stores it in the "text" variable
stringstream T=stringstream(text);// Stores the string variable in a stringstream
/* Reads from the stringstream a portion of text up to the next space character and stores it in the "word" variable */
while(getline(T, word, ' '))
{
n++;// counts words (loop iterations)
cout << "The text contains " << n << " words" << endl;
return 0;
In the previous example, a line of text is first read and stored in the variable text, of type string. Then, a data stream ("sstream" in English) is introduced, and the string is transferred into that data stream.
Next, within the while loop, the function getline() is used with three parameters: the first parameter is the stream as the data source, the second is the string variable as the destination, and the third is a character, in this case, the space character, which acts as the delimiter up to which text will be read from the initially loaded string.
This means that words will be extracted from the text one by one until getline() returns string::npos, indicating that the text from the stream has been read completely.
The text could also be read directly from standard input, avoiding the need for the sstream object. In that case, it would look like this:
using namespace std;
int main()
{
int n = 0; //loop counter
/*Reads from standard input(cin) a part of the text until the next space character and stores it in the variable "word"*/
while(getline(cin, word, ' '))
{
n++;//counts words (iterations)
cout << "There are " << n << " words " << endl;
return 0;
Test your code in the editor below
Basic string operations
Assigning the value of one string to another string
We can assign the value of one string to another.
string str1 = "Hello!";
string str2;
str2 = str1;
One string can be initialized with another as shown in the following example.
string str1 = "Hello!";
string str2 = str1;
"Concatenating" two strings
Two strings (or more) can be concatenated using the addition operation + just like we did with adding numbers.
#include <iostream>
#include <string>
using namespace std;
int main() {
string full_name;
string first_name = "Nenad";
string last_name = "Milenkovic";
full_name = first_name + " " + last_name;
cout << full_name << endl;
return 0;
}
After the program runs, the variable full_name will contain the string "Nenad Milenkovic".
String length
To determine the length of a string, we use the length function from the string library.
string str1;
str1.length()
Program example:
#include <iostream>
#include <string>
using namespace std;
int main() {
string city_name;
int text_length;
cout << "Enter the city name: ";
getline(cin, city_name);
text_length = city_name.length() - 1; // Subtracting 1 for the space
cout << endl << endl;
cout << "City: " << city_name << endl;
cout << "The city name contains " << text_length << " characters." << endl;
return 0;
}
Program output example:
Enter the city name: Banatski Karlovac
City: Banatski Karlovac
The city name contains 16 characters.
String comparison
To compare strings, we use logical operators >, <, ==, !=, >=, <=, which allow us to compare strings lexicographically, i.e., alphabetically. For example, 'c' comes before 'd' lexicographically. Also, 'aabc' comes before 'abc' because the comparison is not done based on string length, but on lexicographical order.
Example 1:
bool b;
b = ("abak" == "abak"); // true
b = ("Ab" < "AA"); // false, because lowercase 'b' is lexicographically larger than uppercase 'A'
Example 2: Checking password accuracy
An example program that checks whether the entered password matches @n0nimus_@n0nimus:
#include <iostream>
#include <string>
using namespace std;
int main() {
string password;
cin >> password;
if (password == "@n0nimus_@n0nimus") {
cout << "Correct password" << endl;
} else {
cout << "Incorrect password";
}
return 0;
}
Testing characters using header functions < cctype >
These functions allow you to:
- Check if a character is a letter (isalpha)
- Check if a character is a digit (isdigit)
- Case-sensitive (islower, isupper)
- Check for whitespace (isspace)
- Convert between lowercase and uppercase (tolower, toupper), etc.
Below, we will see examples of how these functions are used and how we can use them in everyday C++ programming.
Some functions from the "cctype" header
- isalnum(ch), Is ch a letter or a digit?
- isalpha(ch), Is ch a letter?
- islower(ch), Is ch a lowercase letter?
- isupper(ch), Is ch an uppercase letter?
- isdigit(ch), Is ch a decimal digit?
- isspace(ch), Is ch a whitespace character (space, tab, newline)?
- ispunct(ch), Is ch a punctuation character?
- iscntrl(ch), Is ch a control character (like backspace or enter)?
- tolower(ch), Converts uppercase letter ch to lowercase.
- toupper(ch), Converts lowercase letter ch to uppercase.
Example of using functions from the <cctype> header
Write a C++ program that allows the user to enter a single character from the keyboard, and then examines and prints its properties using the functions in the <cctype> header.
The program should examine the following characteristics of the entered character:
- Is it a letter or a digit (isalnum)
- Is it a letter (isalpha)
- Is it a digit (isdigit)
- Is it a lowercase letter (islower) and, if so, display its uppercase
- Is it an uppercase letter (isupper) and, if so, display its lowercase
- Is it a whitespace (space, tab, newline) (isspace)
- Is it a punctuation character (ispunct)
- Is it a control character (iscntrl)
#include <cctype> // Header with functions for character testing
using namespace std;
int main() {
cout << "Enter a character: ";
cin >> ch;
// Check if the character is a letter or a digit
if (isalnum(ch)) {
// Check if the character is a letter
if (isalpha(ch)) {
// Check if the character is a digit
if (isdigit(ch)) {
// Check if the character is a lowercase letter
if (islower(ch)) {
cout << "Uppercase letter: " << (char)toupper(ch) << '\n';
// Check if the character is an uppercase letter
if (isupper(ch)) {
cout << "Lowercase letter: " << (char)tolower(ch) << '\n';
// Check if the character is a whitespace character (space, tab, newline)
if (isspace(ch)) {
// Check if the character is a punctuation character
if (ispunct(ch)) {
// Check if the character is a control character
if (iscntrl(ch)) {
return 0;
Functions for searching within a string
To search for the position of a character or part of the text within a larger string, the find() function is used.
For example, to find the occurrence of "is" within the given text:
string str1 = "Observed in hyperspace dimensions, galaxies appear as mere dots - and so it is throughout the Universe. We haven't even reached any other galaxy yet, nor, as far as we know, has any intelligent species from another galaxy come among us; however, one day this may come to an end.";
int position, position2, position3;
position = str1.find("is"); // e.g. 76
position2 = str1.find("is", 250); // e.g. 260
position3 = str1.rfind("is"); // e.g. 260
The find() function returns the position of the first occurrence of the given character or substring, and if it does not find it, it returns the value string::npos.
Similarly, the rfind() (reverse find) function searches the string from the end and returns the position of the last occurrence of the given character or substring.
The rfind() function returns the position of the last occurrence before the given position, or finds the first occurrence when moving backward.
Substrings
We use the substr function from the <string> header.
Example 1:
string text = " Observed in hyperspace dimensions, galaxies appear as mere dots.";
string substring = text.substr(3, 11);
The variable substring contains the string "smatrano", while the variable text remains unchanged. The first parameter represents the starting position of the substring (positions start at 0), and the second parameter represents the length of the substring.
If the second parameter is omitted, the substr function returns the substring starting from the specified starting position to the end of the string. For example:
string text = " galaxies appear as mere dots?";
string substring = text.substr(4);
The first parameter must specify a valid existing position within the string, otherwise the function's behavior will be undefined. The second parameter, in combination with the first, could cause the string's length to be exceeded. In that case, the substr function returns all characters from the specified starting position to the end of the string. For example:
string text = "012345";
string fragment = text.substr(2, 3); // OK
fragment = text.substr(6, 2); // Undefined behavior - starting position out of range
fragment = text.substr(3, 10); // Returns all available characters from position 3
In this case, the command fragment = text.substr(3,10); has the same effect as fragment = text.substr(3,3); if there are no more than 3 characters from position 3.
Deleting and inserting substrings
The erase function has two input parameters, which determine the substring (starting position and number of characters in the substring) to be deleted from the string, as shown in the following example:
string text = "This is a test";
text.erase(0, 7);
After executing the command text.erase(0,7), the string text contains "test". The substring starting from position 0 ('T' in "This is ") and having 7 characters (including spaces) is deleted from the string, shortening it – a good analogy is using the [Delete] key in text editors.
Instead of deleting the substring, it can be replaced with another string, as shown in the following example:
string text = "This is a test";
text.replace(4, 2, "not");
After executing the command text.replace(4,2,"not"), the string text contains "This not a test". Notice that we replaced a substring of two characters with a string of four characters, which is allowed. The replace function is similar to the insert option in text editors.
Splitting strings using the "," separator
Suppose we read a line of text from the standard input, where the text contains a comma (","). The task is to split the text into two parts: the part before the comma (left side) and the part after the comma (right side).
For example, if the input reads: "Masarikova 18, Belgrade", the output should print in two lines:
string address = "Masarikova 18, Belgrade";
size_t commaPos = address.find(",");
string leftPart = address.substr(0, commaPos);
string rightPart = address.substr(commaPos + 1);
cout << leftPart << endl;
cout << rightPart << endl;
After executing this code, the output will be:
Masarikova 18
Belgrade
Solution: The task can be solved by first reading a line of text using the getline method:
getline(cin, inputLine);
Then, the position of the character "," in the input line is determined using the find_first_of function, which takes a separator (in this case ",") as a parameter and returns the position of the first occurrence of the separator or, if not found, the value -1:
sepInd = inputLine.find_first_of(",");
Finally, two substrings are extracted using the substr method, utilizing the previously determined position:
str1 = inputLine.substr(0, sepInd);
str2 = inputLine.substr(sepInd + 1);
Complete code:
#include <iostream>
#include <string>
using namespace std;
int main() {
string inputLine;
string delimiter = ",";
string part1, part2;
int separatorIndex;
cout << "Enter a line of text: " << endl;
getline(cin, inputLine);
separatorIndex = inputLine.find_first_of(delimiter);
part1 = inputLine.substr(0, separatorIndex);
part2 = inputLine.substr(separatorIndex + 1);
cout << part1 << endl;
cout << part2 << endl;
return 0;
}
Advanced Operations with std::string
in C++
The std::string class in C++ offers a wide range of methods for advanced manipulation of text data. In addition to basic operations like searching, extracting, and replacing substrings, there are additional techniques that allow for more flexible and efficient handling of strings. Below are some of the advanced operations:
String Concatenation
Concatenation, or joining of strings, can be performed using the + operator or the append() method. This allows simple concatenation of multiple text values.
Example:
#include <iostream>
#include <string>
using namespace std;
int main() {
string s1 = "Hello, ";
string s2 = "world!";
string result = s1 + s2; // Joining strings using the + operator
cout << result << endl;
return 0;
}
Inserting Substrings
The insert() function allows inserting one string into another at a specific position, which is useful for dynamically modifying text.
Example:
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "Welcome!";
s.insert(6, "world "); // Inserting "world " at position 6
cout << s << endl;
return 0;
}
Changing Letter Case
Using the std::transform function from <algorithm> and functions from <cctype>, a string can be converted to uppercase or lowercase letters.
Example:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
int main() {
string s = "Welcome to C++";
transform(s.begin(), s.end(), s.begin(), ::toupper);
cout << s << endl; // Prints "WELCOME TO C++"
return 0;
}
Tokenizing a String
Splitting a string into multiple parts using a specific separator can be achieved by combining the find() and substr() methods. This is useful for parsing input data.
Example:
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "Mark,Anna,Peter,John";
size_t pos;
string token;
while ((pos = s.find(',')) != string::npos) {
token = s.substr(0, pos);
cout << token << endl;
s.erase(0, pos + 1);
}
cout << s << endl; // Prints last token
return 0;
}
By implementing these advanced operations, working with std::string becomes more flexible and efficient, and developers can tailor their applications to the demands of more complex text manipulation.
Previous
|< Two-dimensional dynamic arrays in c++ |
Next
Pointers in C++ >| |