I have a vector
containing strings
that follow the format of text_number-number
Eg: Example_45-3
I only want the first number (45
in the example) and nothing else which I am able to do with my current code:
std::vector<std::string> imgNumStrVec;
for(size_t i = 0; i < StrVec.size(); i++){
std::vector<std::string> seglist;
std::stringstream ss(StrVec[i]);
std::string seg, seg2;
while(std::getline(ss, seg, '_')) seglist.push_back(seg);
std::stringstream ss2(seglist[1]);
std::getline(ss2, seg2, '-');
imgNumStrVec.push_back(seg2);
}
Are there more streamlined and simpler ways of doing this? and if so what are they?
I ask purely out of desire to learn how to code better as at the end of the day, the code above does successfully extract just the first number, but it seems long winded and round-about.
Using @Pixelchemist's answer and e.g.
std::stoul
:This should be more efficient than Ashot Khachatryan's solution. Note the use of
'_'
and'-'
instead of"_"
and"-"
. And also, the starting position of the search for'-'
.If you need a number instead of a string, like what Alexandr Lapenkov's solution has done, you may also want to try the following:
I can think of two ways of doing it:
The 'best' way to do this in C++11 and later is probably using regular expressions, which combine high expressiveness and high performance when the test is repeated often enough.
The following code demonstrates the basics. You should
#include <regex>
for it to work.updated for C++11 2018-12-04
I tried to update this answer to use C++11 on my machine but failed because my g++ compiler does not have full
<regex>
support... so I kept getting uncaughtstd::regex_error
code=4
(i.e. "missing bracket") exceptions for any regex with bracket character classesstd::regex("[0-9]")
.Apparently full support for C++11
<regex>
was implemented and released for g++ version 4.9.x and on Jun 26, 2015. Hat tip to SO questions #1 and #2 for figuring out the compiler version needing to be 4.9.x.Here is the C++11 code that should work but I wasn't able to test it:
boost solution that only requires C++98
Minimal implementation example that works on many strings (not just strings of the form "text_45-text":
console output:
Other example strings that this would work on:
For this example I used g++ on Linux with
#include <boost/regex.hpp>
and-lboost_regex
. You could also use C++11x regex.Feel free to edit my solution if you have a better regex.
Commentary:
If there aren't performance constraints, using Regex is ideal for this sort of thing because you aren't reinventing the wheel (by writing a bunch of string parsing code which takes time to write/test-fully).
Additionally if/when your strings become more complex or have more varied patterns regex easily accommodates the complexity. (The question's example pattern is easy enough. But often times a more complex pattern would take 10-100+ lines of code when a one line regex would do the same.)
You can also use the built in
find_first_of
andfind_first_not_of
to find the first "numberstring" in any string.