Right way to split an std::string into a vector<string>
For space separated strings, then you can do this:
std::string s = "What is the right way to split a string into a vector of strings";
std::stringstream ss(s);
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> vstrings(begin, end);
std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
Output:
What
is
the
right
way
to
split
a
string
into
a
vector
of
strings
string that have both comma and space
struct tokens: std::ctype<char>
{
tokens(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
typedef std::ctype<char> cctype;
static const cctype::mask *const_rc= cctype::classic_table();
static cctype::mask rc[cctype::table_size];
std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));
rc[','] = std::ctype_base::space;
rc[' '] = std::ctype_base::space;
return &rc[0];
}
};
std::string s = "right way, wrong way, correct way";
std::stringstream ss(s);
ss.imbue(std::locale(std::locale(), new tokens()));
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> vstrings(begin, end);
std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
Output:
right
way
wrong
way
correct
way
how can i split a vector <string > and acces what i need in it?
As user31264 suggested you could write a split function and split every line you got into its words.
IMHO this is a better and more flexible split function though:
#include <vector>
#include <string>
#include <sstream>
std::vector<std::string> split(const std::string& str, char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(str);
while(std::getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
What that function does is creating a stringstream
out of your string
(your line) and extracting words delimited by char delimiter
by using getline()
on that stream.
So while reading your file with getline()
you could pass every line into that split function with
auto words = split(line, ' ');
and iterate over all words that line contains.
String into vector
Your code won't work; it'll store the string ss.size()
times in the vector.
You might want to use a string stream to split the string:
std::stringstream stream(ss);
std::string line;
while (std::getline(stream, line)) {
test1.push_back(line);
}
Note that the newline character will be discarded. If you want to keep it, push_back(line + "\n");
.
Splitting a string withisalnum and store into a vector of strings
The std::replace_if
trick I commented on turned out to not be quite as trivial as I thought it was because std::isalnum
doesn't return bool
.
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
#include <algorithm>
#include <sstream>
#include <iterator>
int main()
{
std::vector<std::string> result;
std::string something = "bob-michael !#mi%@pa hi3llary-tru1mp";
// I expected replace_if(something.begin(), something.end(), &isalnum, " ");
// would work, but then I did a bit of reading and found is alnum returned int,
// not bool. resolving this by wrapping isalnum in a lambda
std::replace_if(something.begin(),
something.end(),
[](char val)->bool {
return std::isalnum(val) == 0;
},
' ');
std::stringstream pie(something);
// read stream into vector
std::copy(std::istream_iterator<std::string>(pie),
std::istream_iterator<std::string>(),
std::back_inserter<std::vector<std::string>>(result));
// prove it works
for(const std::string & str: result)
{
std::cout << str << std::endl;
}
}
How to find out if a std::vector in a string in cpp?
Initialize bool status = true;
and remove status = true;
. You start with the assumption that the string contains all words. Then, you iterate over the list of words and check each word. If a word doesn't exist, set status = false;
.
Store the position of the last result and start the next search at that position.
#include <iostream>
#include <vector>
int main()
{
std::string input_str1 = "Good morning, hello, a beautiful world";//true
std::string input_str2 = "what a wonderful world, hello!"; //false, but I only can return true
//item = "...hello...world..."
std::vector<std::string> item;
item.push_back("hello");
item.push_back("world");
bool status = true;
std::string::size_type pos = 0;
for (auto sub_item : item)
{
std::cout << sub_item << ' ';
pos = input_str2.find(sub_item, pos);
if (pos == std::string::npos)
{
status = false;
break;
}
}
std::cout << status;
}
Output
hello world 0
Parse (split) a string in C++ using string delimiter (standard C++)
You can use the std::string::find()
function to find the position of your string delimiter, then use std::string::substr()
to get a token.
Example:
std::string s = "scott>=tiger";
std::string delimiter = ">=";
std::string token = s.substr(0, s.find(delimiter)); // token is "scott"
The
find(const string& str, size_t pos = 0)
function returns the position of the first occurrence ofstr
in the string, ornpos
if the string is not found.The
substr(size_t pos = 0, size_t n = npos)
function returns a substring of the object, starting at positionpos
and of lengthnpos
.
If you have multiple delimiters, after you have extracted one token, you can remove it (delimiter included) to proceed with subsequent extractions (if you want to preserve the original string, just use s = s.substr(pos + delimiter.length());
):
s.erase(0, s.find(delimiter) + delimiter.length());
This way you can easily loop to get each token.
Complete Example
std::string s = "scott>=tiger>=mushroom";
std::string delimiter = ">=";
size_t pos = 0;
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
std::cout << token << std::endl;
s.erase(0, pos + delimiter.length());
}
std::cout << s << std::endl;
Output:
scott
tiger
mushroom
Related Topics
What Exactly Is the "Immediate Context" Mentioned in the C++11 Standard For Which Sfinae Applies
Boost Asio Async_Write: How to Not Interleaving Async_Write Calls
Why Does C++11'S Lambda Require "Mutable" Keyword For Capture-By-Value, by Default
What Exactly Is a Reentrant Function
What's the Difference Between a Header File and a Library
Using Local Classes With Stl Algorithms
Why Do Constant Expressions Have an Exclusion For Undefined Behavior
Accessing Inherited Variable from Templated Parent Class
Replace Substring With Another Substring C++
Why Are Function Pointers and Data Pointers Incompatible in C/C++
Why Are C++ Inline Functions in the Header