Skip to content

Instantly share code, notes, and snippets.

@noureddin
Last active February 3, 2018 21:47
Show Gist options
  • Save noureddin/5c372984d9b47b0d683607c130066e0f to your computer and use it in GitHub Desktop.
Save noureddin/5c372984d9b47b0d683607c130066e0f to your computer and use it in GitHub Desktop.
modern replacement for strtok
#include <string>
#include <vector>
// If you are using strtok, or a variant like strtok_r or strtok_s, in your
// C++ code, you may be interested in this instead.
//
// This header contains a function called `split`, that takes a string, and
// an array of delimiting characters, and breaks the string on the delimiters,
// in a way similar to strtok, and returns a vector of strings representing
// the tokens.
//
// In brief, split is like strtok but is thread-safe and is called only once
// and returns a vector of tokens.
//
// Example:
// // tokenizing
// std::vector<std::string> tokens = split("ab c d efg h ", " ");
// // using the tokens
// for (size_t i = 0; i < tokens.size(); ++i)
// std::cout << tokens[i] << "\n";
// Output:
// ab
// c
// d
// efg
// h
// License: CC0 (Public Domain)
// splits the given string on every given delimiter and returns a vector
// of strings.
std::vector<std::string>
split(
const std::string& input,
const std::string& delims)
{
std::vector<std::string> ret;
for (size_t start = 0, pos; ; start = pos + 1) {
pos = input.find_first_of(delims, start);
std::string token = input.substr(start, pos - start);
if (token.length() > 0) // ignore empty tokens
ret.push_back(token);
if (pos == std::string::npos) break;
}
return ret;
}
#include <iostream>
#include "split.hpp" // includes string and vector
// This file is used mainly for testing split() during it developing;
// you don't need to get it.
using std::string;
using std::vector;
using std::cout;
#define test_split(s, d) do { \
vector<string> v = split(s, d); \
cout << "\n\"" s << "\" separated by \"" d "\" " \
<< "has " << v.size() << " tokens\n"; \
for (size_t i = 0, len = v.size(); i < len; ++i) \
cout << " -> " << v[i] << "\n"; \
} while (0)
int main()
{
if (0) { // example
std::vector<std::string> tokens = split("ab c d efg h ", " ");
for (size_t i = 0; i < tokens.size(); ++i)
std::cout << tokens[i] << "\n";
}
if (1) { // testing split
test_split("Hello", "l");
test_split("Helalo", "l");
test_split("Helloo", "l");
test_split("Helaloo", "l");
test_split("Hellool", "l");
test_split("Helalool", "l");
test_split("lHellool", "l");
test_split("lHelalool", "l");
test_split("lHelloo", "l");
test_split("lHelaloo", "l");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment