Variables » Strings » Common Problems
Forgotten include
int main()
{
std::string s = "Hello";
}
Potential error message
- GCC
- MSVC
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() {
error C2039: 'string': is not a member of 'std'
predefined C++ types (compiler internal)(339): message : see declaration of 'std'
error C2065: 'string': undeclared identifier
Solution
Add #include <string>
to the top of your file.
Treating numbers as strings
#include <string>
int main()
{
std::string s = 123;
}
Potential error message:
- GCC
- MSVC
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;
| ^~~
error C2440: 'initializing': cannot convert from 'int' to 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
note: No constructor could take the source type, or constructor overload resolution was ambiguous
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
#include <string>
int main()
{
std::string s = "123";
s *= 15;
}
Potential error message:
- GCC
- MSVC
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;
| ~~^~~~~
error C2676: binary '*=': 'std::string' does not define this operator or a conversion to a type acceptable to the predefined operator
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
#include <string>
int main()
{
std::string s = "Hello " + "World";
}
Potential error message:
- GCC
- MSVC
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]
error C2110: '+': cannot add two pointers
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
#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:
int age;
std::string full_name;
std::cin >> age;
std::cin.ignore();
std::getline(std::cin, full_name);