Question
In standard C++, std::getline works well when the delimiter is a single character. For example:
using namespace std;
string parsed;
string input = "text to be parsed";
stringstream input_stringstream(input);
if (getline(input_stringstream, parsed, ' '))
{
// do some processing
}
However, how can you split a string when the delimiter is a string instead of a single character?
For example, given this input:
string input = "scott>=tiger";
How can you split it using ">=" as the delimiter so that you get:
scotttiger
Short Answer
By the end of this page, you will understand why std::getline cannot split on multi-character delimiters, and how to use std::string::find and std::string::substr to split strings using string delimiters like ">=" in C++. You will also see common patterns, mistakes, and a small practical project.
Concept
In C++, std::getline supports only a single character delimiter. That works for cases like splitting by a space, comma, or colon, but not for delimiters made of multiple characters such as ">=", "--", or "||".
When your delimiter is a string, the usual approach in standard C++ is:
- Search for the delimiter inside the string using
std::string::find - Extract the part before it using
std::string::substr - Extract the part after it using
std::string::substragain
This matters because real programs often parse structured text that uses multi-character separators, such as:
- configuration entries like
key=>value - log data like
time||message - simple query expressions like
name>=john - custom file formats and protocols
Understanding this pattern is useful because find + substr is one of the most common standard-library techniques for string parsing in C++. It is simple, readable, and does not require non-standard libraries.
Mental Model
Think of a string as a long strip of paper.
findhelps you locate where a marker appears on the stripsubstrlets you cut out pieces of the strip
If the string is:
scott>=tiger
and your marker is:
>=
then you:
- find where
">="starts - cut everything before it →
scott - cut everything after it →
tiger
So instead of saying “split by one character,” you are really saying “find this substring, then slice around it.”
Syntax and Examples
Core idea
Use:
find(delimiter)to locate the delimitersubstr(start, length)to extract pieces
Example: split once by a string delimiter
#include <iostream>
#include <string>
int main()
{
std::string input = "scott>=tiger";
std::string delimiter = ">=";
std::size_t pos = input.find(delimiter);
if (pos != std::string::npos)
{
std::string left = input.substr(0, pos);
std::string right = input.substr(pos + delimiter.length());
std::cout << "Left: " << left << '\n';
std::cout << "Right: " << right << '\n';
}
else
{
std::cout << "Delimiter not found\n";
}
}
Output
Left: scott
Right: tiger
Why this works
Step by Step Execution
Consider this code:
#include <iostream>
#include <string>
int main()
{
std::string input = "scott>=tiger";
std::string delimiter = ">=";
std::size_t pos = input.find(delimiter);
if (pos != std::string::npos)
{
std::string left = input.substr(0, pos);
std::string right = input.substr(pos + delimiter.size());
std::cout << left << '\n';
std::cout << right << '\n';
}
}
Step-by-step
1. Store the input
std::string input = "scott>=tiger";
The string contains 12 characters:
s c o t t > = t i g e r
0 1 2 3 4 5 6 7 8 9 10 11
2. Store the delimiter
std::string delimiter = ">=";
Its length is 2.
3. Find the delimiter position
Real World Use Cases
Multi-character delimiters appear more often than beginners expect.
Common uses
- Parsing configuration lines
- Example:
host=>localhost
- Example:
- Processing simple expressions
- Example:
age>=18
- Example:
- Reading custom file formats
- Example:
header||body
- Example:
- Handling logs or exported data
- Example:
timestamp-->message
- Example:
- Tokenizing user input in small tools
- Example:
username::role
- Example:
Practical example: parsing a filter rule
std::string rule = "price>=100";
std::string delimiter = ">=";
std::size_t pos = rule.find(delimiter);
if (pos != std::string::npos)
{
std::string field = rule.substr(0, pos);
std::string value = rule.substr(pos + delimiter.size());
}
This could be used in a search tool, reporting script, or command parser.
Real Codebase Usage
In real codebases, developers usually wrap this logic in a reusable function instead of writing find and substr repeatedly.
Common pattern: return two parts
#include <string>
#include <utility>
std::pair<std::string, std::string> split_once(const std::string& input, const std::string& delimiter)
{
std::size_t pos = input.find(delimiter);
if (pos == std::string::npos)
{
return {input, ""};
}
return {
input.substr(0, pos),
input.substr(pos + delimiter.size())
};
}
Guard clause pattern
A guard clause checks bad or special cases early:
if (delimiter.empty())
{
// handle invalid delimiter
}
This is important because splitting by an empty delimiter is usually not meaningful.
Validation pattern
Developers often validate input before parsing:
Common Mistakes
1. Trying to use std::getline with a string delimiter
This does not work because the third parameter must be a single char.
std::getline(stream, parsed, ">="); // wrong
Use find and substr instead.
2. Forgetting to check whether the delimiter exists
Broken code:
std::size_t pos = input.find(delimiter);
std::string left = input.substr(0, pos);
std::string right = input.substr(pos + delimiter.size());
If the delimiter is not found, pos is std::string::npos, which can lead to incorrect behavior.
Better:
std::size_t pos = input.find(delimiter);
if (pos != std::string::npos)
{
std::string left = input.substr(0, pos);
std::string right = input.(pos + delimiter.());
}
Comparisons
Single-character vs string delimiter parsing
| Approach | Delimiter type | Standard C++ support | Best for |
|---|---|---|---|
std::getline(stream, text, ',') | Single character | Yes | Simple tokenizing from streams |
find + substr | String or character | Yes | Splitting by multi-character delimiters |
find vs stringstream
| Tool | Good at | Limitation |
|---|---|---|
stringstream + |
Cheat Sheet
Quick reference
Split once by string delimiter
std::string input = "scott>=tiger";
std::string delimiter = ">=";
std::size_t pos = input.find(delimiter);
if (pos != std::string::npos)
{
std::string left = input.substr(0, pos);
std::string right = input.substr(pos + delimiter.size());
}
Important methods
find(str)→ returns index of first match orstd::string::npossubstr(start, length)→ returns part of a stringsubstr(start)→ returns fromstartto endsize()orlength()→ number of characters
Rules
std::getlineonly accepts achardelimiter- Use
findfor multi-character delimiters - Always check
pos != std::string::npos
FAQ
Can std::getline use a string delimiter in C++?
No. The delimiter parameter for std::getline is a single char, not a std::string.
What is the standard C++ way to split by ">="?
Use std::string::find to locate the delimiter and std::string::substr to extract the parts before and after it.
What happens if the delimiter is not found?
find returns std::string::npos. You should check for that before calling substr based on the found position.
How do I split a string multiple times using the same delimiter?
Use a loop with find, extract the token, remove or skip the processed part, and continue until no delimiter remains.
Is find better than regular expressions for this task?
For a fixed delimiter like ">=", yes. It is simpler, easier to read, and usually more efficient.
Can I split by more than one possible delimiter?
Yes, but you need extra logic, such as checking several delimiters or using a more advanced parser.
Mini Project
Description
Build a small C++ parser that reads expressions in the form left>=right and separates them into two values. This demonstrates how to parse strings with a multi-character delimiter using only the standard library.
Goal
Create a program that splits an input string using a string delimiter and prints the left and right parts safely.
Requirements
- Read or define an input string that contains a multi-character delimiter.
- Use
std::string::findto locate the delimiter. - Print the text before and after the delimiter.
- Handle the case where the delimiter is missing.
- Reject an empty delimiter.
Keep learning
Related questions
Advantages of Brace Initialization in C++
Learn why C++ brace initialization is often clearer and safer than other object initialization styles, with examples and common pitfalls.
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Aggregates, Trivial Types, Trivially Copyable Types, and PODs Explained
Learn what aggregates, trivial types, trivially copyable types, and PODs mean in C++, how they differ, and why they matter.