Skip to main content

Variables » Strings » Common Problems

Forgotten include

❌ Erroneous Code
int main()
{
std::string s = "Hello";
}

Potential error message

In function 'int main()':
error: 'string' is not a member of 'std'
2 | std::string s = "Hello";
| ^~~~~~
note: 'std::string' is defined in header '<string>'; did you forget to '#include <string>'?
+++ |+#include <string>
1 | int main() {

Solution

Add #include <string> to the top of your file.

Treating numbers as strings

❌ Erroneous Code
#include <string>

int main()
{
std::string s = 123;
}

Potential error message:

In function 'int main()':
error: conversion from 'int' to non-scalar type 'std::string' {aka 'std::__cxx11::basic_string<char>'} requested
4 | std::string s = 123;
| ^~~

Solution

Use std::to_string to convert an integer to a string. See Conversions between numbers and strings and Numbers and Strings for more information.

Treating strings as numbers

❌ Erroneous Code
#include <string>

int main()
{
std::string s = "123";
s *= 15;
}

Potential error message:

In function 'int main()':
error: no match for 'operator*=' (operand types are 'std::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')
5 | s *= 15;
| ~~^~~~~

Solution

Use std::stoi or std::stof to convert a string into an algebreic value. See Conversions between numbers and strings and Numbers and Strings for more information.

Concatenating two string literals

❌ Erroneous Code
#include <string>

int main()
{
std::string s = "Hello " + "World";
}

Potential error message:

In function 'int main()':
error: invalid operands of types 'const char [7]' and 'const char [6]' to binary 'operator+'
5 | std::string s = "Hello " + "World";
| ~~~~~~~~ ^ ~~~~~~~
| | |
| | const char [6]
| const char [7]

Solution

Whenever you see "TEXT" in a C++ file, that is known as a string literal. Basically, a fancy term for saying that this is a hardcoded text value. Crucially, however, the type of a string literal is not std::string. Rather, it is const char[N] where N is the length of the text + 1. The GCC error above showcases this best.

const char[N] is called an array. We will cover arrays in a later chapter, but the important knowledge here is that you cannot add two arrays together as they are not numbers. std::string is what provides us ability to concatenate strings via +.

The easiest way to fix this is to simply combine the string literals yourself like "Hello World".

Skipping input with std::getline

⚠️ Buggy Code
#include <string>

int main()
{
int age;
std::string full_name;

std::cout << "Enter your age: ";
std::cin >> age;

std::cout << "Enter your full name: ";
std::getline(std::cin, full_name); // This line is seemingly skipped

std::cout << "\nYour name is " << full_name << " and your age is " << age;
}

Unexpected Behavior

You may find that when using std::getline after doing some form of std::cin >> ..., that it appears to skip the std::getline. In the above example, it will ask your age, you would input say 23, and it will ask your full name but not let you enter a name. Instead, it will immedaitely output Your name is and your age is 23.

Solution

Understanding why it does this is a bit tricky. The key aspect to remember is when you use std::cin >> ..., it will take input from stdin until it sees whitespace (a space, a newline, or a tab). When you press Enter on your keyboard to input your age, it places a newline character \n onto stdin. std::cin then reads the number you typed, and stops at that newline without removing the \n character.

std::getline uses the presence of these \n characters to determine where a full line ends. So, when it attempts to read from stdin (std::cin) to read a line up to the next \n, it immediately sees the \n character that was left by the previous std::cin >> age;. Therefore, it interprets this as an empty line and sets full_name to be an empty string "".

The solution to this is another method called ignore. This method will tell std::cin to skip the remaining newline character that was left from the previous operation. Whenever you plan on using std::getline after a std::cin >> ... operation, you should put the method call std::cin.ignore(); in between, like in the abridged example below:

How to use the ignore method
int age;
std::string full_name;

std::cin >> age;

std::cin.ignore();

std::getline(std::cin, full_name);

Variables » Strings » Common Problems

Forgotten include

❌ Erroneous Code
int main()
{
std::string s = "Hello";
}

Potential error message

In function 'int main()':
error: 'string' is not a member of 'std'
2 | std::string s = "Hello";
| ^~~~~~
note: 'std::string' is defined in header '<string>'; did you forget to '#include <string>'?
+++ |+#include <string>
1 | int main() {

Solution

Add #include <string> to the top of your file.

Treating numbers as strings

❌ Erroneous Code
#include <string>

int main()
{
std::string s = 123;
}

Potential error message:

In function 'int main()':
error: conversion from 'int' to non-scalar type 'std::string' {aka 'std::__cxx11::basic_string<char>'} requested
4 | std::string s = 123;
| ^~~

Solution

Use std::to_string to convert an integer to a string. See Conversions between numbers and strings and Numbers and Strings for more information.

Treating strings as numbers

❌ Erroneous Code
#include <string>

int main()
{
std::string s = "123";
s *= 15;
}

Potential error message:

In function 'int main()':
error: no match for 'operator*=' (operand types are 'std::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')
5 | s *= 15;
| ~~^~~~~

Solution

Use std::stoi or std::stof to convert a string into an algebreic value. See Conversions between numbers and strings and Numbers and Strings for more information.

Concatenating two string literals

❌ Erroneous Code
#include <string>

int main()
{
std::string s = "Hello " + "World";
}

Potential error message:

In function 'int main()':
error: invalid operands of types 'const char [7]' and 'const char [6]' to binary 'operator+'
5 | std::string s = "Hello " + "World";
| ~~~~~~~~ ^ ~~~~~~~
| | |
| | const char [6]
| const char [7]

Solution

Whenever you see "TEXT" in a C++ file, that is known as a string literal. Basically, a fancy term for saying that this is a hardcoded text value. Crucially, however, the type of a string literal is not std::string. Rather, it is const char[N] where N is the length of the text + 1. The GCC error above showcases this best.

const char[N] is called an array. We will cover arrays in a later chapter, but the important knowledge here is that you cannot add two arrays together as they are not numbers. std::string is what provides us ability to concatenate strings via +.

The easiest way to fix this is to simply combine the string literals yourself like "Hello World".

Skipping input with std::getline

⚠️ Buggy Code
#include <string>

int main()
{
int age;
std::string full_name;

std::cout << "Enter your age: ";
std::cin >> age;

std::cout << "Enter your full name: ";
std::getline(std::cin, full_name); // This line is seemingly skipped

std::cout << "\nYour name is " << full_name << " and your age is " << age;
}

Unexpected Behavior

You may find that when using std::getline after doing some form of std::cin >> ..., that it appears to skip the std::getline. In the above example, it will ask your age, you would input say 23, and it will ask your full name but not let you enter a name. Instead, it will immedaitely output Your name is and your age is 23.

Solution

Understanding why it does this is a bit tricky. The key aspect to remember is when you use std::cin >> ..., it will take input from stdin until it sees whitespace (a space, a newline, or a tab). When you press Enter on your keyboard to input your age, it places a newline character \n onto stdin. std::cin then reads the number you typed, and stops at that newline without removing the \n character.

std::getline uses the presence of these \n characters to determine where a full line ends. So, when it attempts to read from stdin (std::cin) to read a line up to the next \n, it immediately sees the \n character that was left by the previous std::cin >> age;. Therefore, it interprets this as an empty line and sets full_name to be an empty string "".

The solution to this is another method called ignore. This method will tell std::cin to skip the remaining newline character that was left from the previous operation. Whenever you plan on using std::getline after a std::cin >> ... operation, you should put the method call std::cin.ignore(); in between, like in the abridged example below:

How to use the ignore method
int age;
std::string full_name;

std::cin >> age;

std::cin.ignore();

std::getline(std::cin, full_name);