How to Get a Substring in C++ with substr()
Pulling a smaller piece out of a string — a file extension, a username, the first word — is everyday work in C++. The substr() method handles all of it. Once you understand its two arguments, slicing strings becomes second nature.
The Basics of substr()
Call substr() on any std::string. It takes a starting position and a length, and returns a brand-new string with that slice:
#include <iostream>
#include <string>
int main() {
std::string text = "Programming in C++";
std::cout << text.substr(0, 11) << "\n"; // Programming
std::cout << text.substr(15) << "\n"; // C++
return 0;
}
Two things to internalise. First, positions start at 0, so position 0 is the P. Second, the second number is a length, not an end position — substr(0, 11) means “11 characters starting at 0.”
Grab Everything After a Position
Leave out the length and substr() returns everything from your starting position to the end of the string. Combine it with find() to slice at a specific character — here, pulling a file’s extension:
#include <iostream>
#include <string>
int main() {
std::string path = "report.pdf";
std::size_t dot = path.find('.');
std::string extension = path.substr(dot + 1);
std::cout << "Extension: " << extension << "\n"; // pdf
return 0;
}
find('.') returns the index of the dot, and substr(dot + 1) takes everything after it. This “find a marker, then slice” pattern is the workhorse of simple text parsing.
A Practical Example: Splitting an Email
Combine the two ideas to split an email address into its user and domain parts at the @:
#include <iostream>
#include <string>
int main() {
std::string email = "ada@example.com";
std::size_t at = email.find('@');
std::string user = email.substr(0, at); // up to the @
std::string domain = email.substr(at + 1); // after the @
std::cout << "User: " << user << "\n"; // ada
std::cout << "Domain: " << domain << "\n"; // example.com
return 0;
}
substr(0, at) takes the characters before the @ (a length of at), and substr(at + 1) takes everything after it. No characters are copied twice, and the original email is left unchanged.
Avoiding the out_of_range Error
There’s one crash to watch for. If the starting position is larger than the string’s length, substr() throws a std::out_of_range exception and your program stops. A quick length check keeps you safe:
#include <iostream>
#include <string>
int main() {
std::string s = "short";
std::size_t pos = 10;
if (pos <= s.length())
std::cout << s.substr(pos) << "\n";
else
std::cout << "Position is out of range\n";
return 0;
}
This matters most when pos comes from find(), which returns std::string::npos (a huge value) when it finds nothing. Always confirm find() succeeded before feeding its result into substr().
Quick Reference
| Goal | Code |
|---|---|
Characters len starting at pos | s.substr(pos, len) |
Everything from pos to the end | s.substr(pos) |
| The whole string (a copy) | s.substr(0) |
| Slice after a found character | s.substr(s.find(c) + 1) |
| Stay safe | check pos <= s.length() first |
Related Articles
- C++ String Handling — the std::string basics
- C++ String Contains a Substring — searching with find()
- C++ Split a String — break text into multiple pieces
- C++ Reverse a String — another common string task
- C++ getline: Read a Full Line of Input — get the strings you’ll slice
Take Your C++ Further
If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.