Find an exact substr in a string - c++

I have a text file which contains the following text
License = "123456"
GeneralLicense = "56475655"
I want to search for License as well as for GeneralLicense.
while (getline(FileStream, CurrentReadLine))
{
if (CurrentReadLine.find("License") != std::string::npos)
{
std::cout << "License Line: " << CurrentReadLine;
}
if (CurrentReadLine.find("GeneralLicense") != std::string::npos)
{
std::cout << "General License Line: " << CurrentReadLine;
}
}
Since the word License also present in the word GeneralLicense so if-statement in the line if (CurrentReadLine.find("License") != std::string::npos) becomes true two times.
How can I specify that I want to search for the exact sub-string?
UPDATE: I can reverse the order as mentioned by some Answers OR check if the License is at Index zero. But isn't there anything ROBOUST (flag or something) which we can speficy to look for the exact match (Something like we have in most of the editors e.g. MS Word etc.).

while (getline(FileStream, CurrentReadLine))
{
if (CurrentReadLine.find("GeneralLicense") != std::string::npos)
{
std::cout << "General License Line: " << CurrentReadLine;
}
else if (CurrentReadLine.find("License") != std::string::npos)
{
std::cout << "License Line: " << CurrentReadLine;
}
}

The more ROBUST search is called a regex:
#include <regex>
while (getline(FileStream, CurrentReadLine))
{
if(std::regex_match(CurrentReadLine,
std::regex(".*\\bLicense\\b.*=.*")))
{
std::cout << "License Line: " << CurrentReadLine << std::endl;
}
if(std::regex_match(CurrentReadLine,
std::regex(".*\\bGeneralLicense\\b.*=.*")))
{
std::cout << "General License Line: " << CurrentReadLine << std::endl;
}
}
The \b escape sequences denote word boundaries.
.* means "any sequence of characters, including zero characters"
EDIT: You could also use regex_search instead of regex_match to search for substrings that match instead of using .* to cover the parts that don't match:
#include <regex>
while (getline(FileStream, CurrentReadLine))
{
if(std::regex_search(CurrentReadLine, std::regex("\\bLicense\\b")))
{
std::cout << "License Line: " << CurrentReadLine << std::endl;
}
if(std::regex_search(CurrentReadLine, std::regex("\\bGeneralLicense\\b")))
{
std::cout << "General License Line: " << CurrentReadLine << std::endl;
}
}
This more closely matches your code, but note that it will get tripped up if the keywords are also found after the equals sign. If you want maximum robustness, use regex_match and specify exactly what the whole line should match.

You can check if the position at which the substring appears is at index zero, or that the character preceding the initial position is a space:
bool findAtWordBoundary(const std::string& line, const std::string& search) {
size_t pos = line.find(search);
return (pos != std::string::npos) && (pos== 0 || isspace(line[pos-1]));
}
Isn't there anything ROBUST (flag or something) which we can specify to look for the exact match?
In a way, find already looks for exact match. However, it treats a string as a sequence of meaningless numbers that represent individual characters. That is why std::string class lacks the concept of "full word", which is present in other parts of the library, such as regular expressions.

You could write a function that tests for the largest match first and then returns what ever information you want about the match.
Something a bit like:
// find the largest matching element from the set and return it
std::string find_one_of(std::set<std::string, std::greater<std::string>> const& tests, std::string const& s)
{
for(auto const& test: tests)
if(s.find(test) != std::string::npos)
return test;
return {};
}
int main()
{
std::string text = "abcdef";
auto found = find_one_of({"a", "abc", "ab"}, text);
std::cout << "found: " << found << '\n'; // prints "abc"
}

If all matches start on pos 0 and none is prefix of an other, then the following might work
if (CurrentReadLine.substr( 0, 7 ) == "License")

You can tokenize your string and do a full comparison with your search key and the tokens
Example:
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
auto tokenizer(const std::string& line)
{
std::vector<std::string> results;
std::istringstream ss(line);
std::string s;
while(std::getline(ss, s, ' '))
results.push_back(s);
return results;
}
auto compare(const std::vector<std::string>& tokens, const std::string& key)
{
for (auto&& i : tokens)
if ( i == key )
return true;
return false;
}
int main()
{
std::string x = "License = \"12345\"";
auto token = tokenizer(x);
std::cout << compare(token, "License") << std::endl;
std::cout << compare(token, "GeneralLicense") << std::endl;
}

Related

What am I doing wrong here with find and string?

I am asking user to enter date in format with slashes. Then I try to find the slashes in the string using find. I get error saying I cannot compare pointer with integer on my if statement. Here is code.
// test inputing string date formats
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string dateString;
int month,day,year;
std::cout << "Enter a date in format of 5/14/1999: ";
std::getline(std::cin,dateString);
std::cout << "You entered " << dateString << std::endl;
if (std::find(dateString.begin(),dateString.end(),"/") != dateString.end()) {
std::cout << "Found slash in date.\n";
}
else {
std::cout << "screwed it up.\n";
}
}
Any help is appreciated.
if (std::find(dateString.begin(),dateString.end(),"/") != dateString.end()) {
"/" is a literal string, or a const char * (actually a const char[2] in this case, to be pedantic, but this is not germane) . The third parameter to std::find, in this case, should be a char, a single character.
You probably meant
if (std::find(dateString.begin(),dateString.end(),'/') != dateString.end()) {
I think you can use
if (dateString.find("/") != std::string::npos) {
std::cout << "Found slash in date.\n";
} else {
std::cout << "screwed it up.\n";
}
to find substring/char in a string. Note that std::string::find() works for char, const char * and std::string.

why does find_first_not_of fail when it hits the end of a string?

On the cppreference.com entry of std::string::find_first_not_of it gives this example of text macro replacement:
#include <string>
#include <iostream>
int main() {
std::string to_search = "Some data with %MACROS to substitute";
std::cout << "Before: " << to_search << '\n';
auto pos = std::string::npos;
while ((pos = to_search.find('%')) != std::string::npos) {
// Permit uppercase letters, lowercase letters and numbers in macro names
const auto after = to_search.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", pos + 1);
// Now to_search[pos] == '%' and to_search[after] == ' ' (after the 'S')
if(after != std::string::npos)
to_search.replace(pos, after - pos, "some very nice macros");
}
std::cout << "After: " << to_search << '\n';
}
This works well, unless the %MACROS is at the end of the string (shown below), in which case find_first_not_of returns std::string::npos and this turns into an infinite loop.
std::string to_search = "Some data with %MACROS";
Why does this specific block of code totally skip the replacement of %MACROS because it's at the end of the string? Does it not consider \0 as "not of" the set of characters it's given?
find_first_not_of() returns npos when it doesn't find a match. In your case, when the macro is at the end of the string, there are no matching characters, thus npos. To handle that condition, simply replace npos with size() before performing the replacement.
Try this:
#include <string>
#include <iostream>
int main() {
std::string to_search = "Some data with %MACROS to substitute";
std::string replace_with = "some very nice macros";
std::string macro_name;
std::cout << "Before: " << to_search << '\n';
std::string::size_type pos = 0;
while ((pos = to_search.find('%', pos)) != std::string::npos)
{
// Permit uppercase letters, lowercase letters and numbers in macro names
auto after = to_search.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", pos + 1);
// if no matching chars, set after past the last char...
if (after == std::string::npos)
after = to_search.size();
auto count = after - pos;
if (count > 1)
{
// extract the macro name and replace the macor only if
// the name actually maps to something worth replacing...
macro_name = to_search.substr(pos + 1, count - 1);
if (macro_name == "MACROS")
{
// found a macro!
to_search.replace(pos, count, replace_with);
// start the next search after the replaced text...
pos += replace_with.size();
continue;
}
// check for other macros as needed...
}
// no matching macro, skip the '%' and search again from the next char...
++pos;
}
std::cout << "After: " << to_search << '\n';
}
Live Demo

How to check for success in c++11 std::regex_replace?

I'd like to do the c++11 equivalent of a perl checked-replacement operation:
my $v = "foo.rat"
if ( $v =~ s/\.rat$/.csv/ )
{
...
}
I can do the replacement without trouble:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string s{ "foo.rat" } ;
std::regex reg{ R"((.*)\.rat$)" } ;
s = std::regex_replace( s, reg, "$1.csv" ) ;
std::cout << s << std::endl ;
s = std::regex_replace( "foo.noo", reg, "$1.csv" ) ;
std::cout << s << std::endl ;
return 0 ;
}
This gives:
foo.csv
foo.noo
Notice that the replace operation on the non-matching expression doesn't throw an error (which is what I expected).
Looking at the regex_replace documentation, it's not obvious to me how to check for the success of the replace operation. I could do a string compare, but that seems backwards?
Try to find match with std::regex_match or std::regex_search, check if something is matched, then replace found portion of string using std::string::replace. That shouldn't lead to performance loss.
Just to add to the accepted answer that it can also be done with a std::regex_iterator. This may be handy when multiple replacements may took place.
Iterator std::regex_iterator repeatedly calls std::regex_search() until all matches are found. If the position of the iterator at the beginning and the position at the end are the same, no match was found.
Function bool regex_replace(std::string &str, const std::string &re, const std::string& replacement) implements this behaviour:
#include <iostream>
#include <regex>
bool regex_replace(std::string &str, const std::string &re, const std::string& replacement) {
std::regex regexp(re);
//Search regex
std::sregex_iterator begin = std::sregex_iterator(str.begin(), str.end(), regexp);
std::sregex_iterator end = std::sregex_iterator();
//replace using iterator
for (std::sregex_iterator i = begin; i != end; ++i)
str.replace(i->position(), i->length(), replacement);
//returns true if at least one match was found and replaced
return (begin != end);
}
This function operates in place. At the end str have the replacements. Only if any replacement was made, the function returns true.
Following code shows how to use it to make multiple replacements and detect if any was made:
int main(int argc, char** argv) {
std::string rgx("[0-9]");
std::string str("0a1b2c3d4e5");
std::string replacement("?");
bool found = regex_replace(str, rgx, replacement);
std::cout << "Found any: " << (found ? "true" : "false") << std::endl;
std::cout << "string: " << str << std::endl;
return 0;
}
The code substitutes every digit for the quotation mark '?':
Found any: true
string: ?a?b?c?d?e?
use std::regex_constants::format_no_copy flag to change the behavior of regex_replace(). look the code below.
the return string will now be empty if match failed.
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string s{ "foo.rat" } ;
std::regex reg{ R"((.*)\.rat$)" } ;
auto rxMatchFlag = std::regex_constants::format_no_copy; //<---use this to modify the behavior of regex_replace when matching failed.
s = std::regex_replace( s, reg, "$1.csv", rxMatchFlag) ;
if(!s.empty()) std::cout << s << std::endl ;
else std::cout << "failed match" << std::endl;
s = std::regex_replace( "foo.noo", reg, "$1.csv", rxMatchFlag) ;
if(!s.empty()) std::cout << s << std::endl ;
else std::cout << "failed match" << std::endl;
return 0 ;
}
for the other flags, look them here
I don't believe there's any direct way to find out whether any replacements were made.
(Don't confuse this with "success / not success", which is not quite the same thing.)

How to find the location of two consecutive spaces in a string

I want to check if my string has two consecutive spaces in it. What's the easiest way to find out?
Use the find() method of std::string. It returns the special constant std::string::npos if the value was not found, so this is easy to check for:
if (myString.find(" ") != std::string::npos)
{
cerr << "double spaces found!";
}
#include <string>
bool are_there_two_spaces(const std::string& s) {
if (s.find(" ") != std::string::npos) {
return true;
} else {
return false;
}
}
This one of Jon Skeet's fave topics: see this presentation
Make search for " " in the string.
Using C:
#include <cstring>
...
addr = strstr (str, " ");
...
string s = "foo bar";
int i = s.find(" ");
if(i != string::npos)
cout << "Found at: " << i << endl;

How do I check if a C++ std::string starts with a certain string, and convert a substring to an int?

How do I implement the following (Python pseudocode) in C++?
if argv[1].startswith('--foo='):
foo_value = int(argv[1][len('--foo='):])
(For example, if argv[1] is --foo=98, then foo_value is 98.)
Update: I'm hesitant to look into Boost, since I'm just looking at making a very small change to a simple little command-line tool (I'd rather not have to learn how to link in and use Boost for a minor change).
Use rfind overload that takes the search position pos parameter, and pass zero for it:
std::string s = "tititoto";
if (s.rfind("titi", 0) == 0) { // pos=0 limits the search to the prefix
// s starts with prefix
}
Who needs anything else? Pure STL!
Many have misread this to mean "search backwards through the whole string looking for the prefix". That would give the wrong result (e.g. string("tititito").rfind("titi") returns 2 so when compared against == 0 would return false) and it would be inefficient (looking through the whole string instead of just the start). But it does not do that because it passes the pos parameter as 0, which limits the search to only match at that position or earlier. For example:
std::string test = "0123123";
size_t match1 = test.rfind("123"); // returns 4 (rightmost match)
size_t match2 = test.rfind("123", 2); // returns 1 (skipped over later match)
size_t match3 = test.rfind("123", 0); // returns std::string::npos (i.e. not found)
You would do it like this:
std::string prefix("--foo=");
if (!arg.compare(0, prefix.size(), prefix))
foo_value = std::stoi(arg.substr(prefix.size()));
Looking for a lib such as Boost.ProgramOptions that does this for you is also a good idea.
Just for completeness, I will mention the C way to do it:
If str is your original string, substr is the substring you want to
check, then
strncmp(str, substr, strlen(substr))
will return 0 if str
starts with substr. The functions strncmp and strlen are in the C
header file <string.h>
(originally posted by Yaseen Rauf here, markup added)
For a case-insensitive comparison, use strnicmp instead of strncmp.
This is the C way to do it, for C++ strings you can use the same function like this:
strncmp(str.c_str(), substr.c_str(), substr.size())
If you're already using Boost, you can do it with boost string algorithms + boost lexical cast:
#include <boost/algorithm/string/predicate.hpp>
#include <boost/lexical_cast.hpp>
try {
if (boost::starts_with(argv[1], "--foo="))
foo_value = boost::lexical_cast<int>(argv[1]+6);
} catch (boost::bad_lexical_cast) {
// bad parameter
}
This kind of approach, like many of the other answers provided here is ok for very simple tasks, but in the long run you are usually better off using a command line parsing library. Boost has one (Boost.Program_options), which may make sense if you happen to be using Boost already.
Otherwise a search for "c++ command line parser" will yield a number of options.
Code I use myself:
std::string prefix = "-param=";
std::string argument = argv[1];
if(argument.substr(0, prefix.size()) == prefix) {
std::string argumentValue = argument.substr(prefix.size());
}
Nobody used the STL algorithm/mismatch function yet. If this returns true, prefix is a prefix of 'toCheck':
std::mismatch(prefix.begin(), prefix.end(), toCheck.begin()).first == prefix.end()
Full example prog:
#include <algorithm>
#include <string>
#include <iostream>
int main(int argc, char** argv) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "Will print true if 'prefix' is a prefix of string" << std::endl;
return -1;
}
std::string prefix(argv[1]);
std::string toCheck(argv[2]);
if (prefix.length() > toCheck.length()) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "'prefix' is longer than 'string'" << std::endl;
return 2;
}
if (std::mismatch(prefix.begin(), prefix.end(), toCheck.begin()).first == prefix.end()) {
std::cout << '"' << prefix << '"' << " is a prefix of " << '"' << toCheck << '"' << std::endl;
return 0;
} else {
std::cout << '"' << prefix << '"' << " is NOT a prefix of " << '"' << toCheck << '"' << std::endl;
return 1;
}
}
Edit:
As #James T. Huggett suggests, std::equal is a better fit for the question: Is A a prefix of B? and is slight shorter code:
std::equal(prefix.begin(), prefix.end(), toCheck.begin())
Full example prog:
#include <algorithm>
#include <string>
#include <iostream>
int main(int argc, char **argv) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "Will print true if 'prefix' is a prefix of string"
<< std::endl;
return -1;
}
std::string prefix(argv[1]);
std::string toCheck(argv[2]);
if (prefix.length() > toCheck.length()) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "'prefix' is longer than 'string'" << std::endl;
return 2;
}
if (std::equal(prefix.begin(), prefix.end(), toCheck.begin())) {
std::cout << '"' << prefix << '"' << " is a prefix of " << '"' << toCheck
<< '"' << std::endl;
return 0;
} else {
std::cout << '"' << prefix << '"' << " is NOT a prefix of " << '"'
<< toCheck << '"' << std::endl;
return 1;
}
}
With C++17 you can use std::basic_string_view & with C++20 std::basic_string::starts_with or std::basic_string_view::starts_with.
The benefit of std::string_view in comparison to std::string - regarding memory management - is that it only holds a pointer to a "string" (contiguous sequence of char-like objects) and knows its size. Example without moving/copying the source strings just to get the integer value:
#include <exception>
#include <iostream>
#include <string>
#include <string_view>
int main()
{
constexpr auto argument = "--foo=42"; // Emulating command argument.
constexpr auto prefix = "--foo=";
auto inputValue = 0;
constexpr auto argumentView = std::string_view(argument);
if (argumentView.starts_with(prefix))
{
constexpr auto prefixSize = std::string_view(prefix).size();
try
{
// The underlying data of argumentView is nul-terminated, therefore we can use data().
inputValue = std::stoi(argumentView.substr(prefixSize).data());
}
catch (std::exception & e)
{
std::cerr << e.what();
}
}
std::cout << inputValue; // 42
}
Given that both strings — argv[1] and "--foo" — are C strings, #FelixDombek's answer is hands-down the best solution.
Seeing the other answers, however, I thought it worth noting that, if your text is already available as a std::string, then a simple, zero-copy, maximally efficient solution exists that hasn't been mentioned so far:
const char * foo = "--foo";
if (text.rfind(foo, 0) == 0)
foo_value = text.substr(strlen(foo));
And if foo is already a string:
std::string foo("--foo");
if (text.rfind(foo, 0) == 0)
foo_value = text.substr(foo.length());
Starting with C++20, you can use the starts_with method.
std::string s = "abcd";
if (s.starts_with("abc")) {
...
}
text.substr(0, start.length()) == start
Using STL this could look like:
std::string prefix = "--foo=";
std::string arg = argv[1];
if (prefix.size()<=arg.size() && std::equal(prefix.begin(), prefix.end(), arg.begin())) {
std::istringstream iss(arg.substr(prefix.size()));
iss >> foo_value;
}
At the risk of being flamed for using C constructs, I do think this sscanf example is more elegant than most Boost solutions. And you don't have to worry about linkage if you're running anywhere that has a Python interpreter!
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
for (int i = 1; i != argc; ++i) {
int number = 0;
int size = 0;
sscanf(argv[i], "--foo=%d%n", &number, &size);
if (size == strlen(argv[i])) {
printf("number: %d\n", number);
}
else {
printf("not-a-number\n");
}
}
return 0;
}
Here's some example output that demonstrates the solution handles leading/trailing garbage as correctly as the equivalent Python code, and more correctly than anything using atoi (which will erroneously ignore a non-numeric suffix).
$ ./scan --foo=2 --foo=2d --foo='2 ' ' --foo=2'
number: 2
not-a-number
not-a-number
not-a-number
I use std::string::compare wrapped in utility method like below:
static bool startsWith(const string& s, const string& prefix) {
return s.size() >= prefix.size() && s.compare(0, prefix.size(), prefix) == 0;
}
C++20 update :
Use std::string::starts_with
https://en.cppreference.com/w/cpp/string/basic_string/starts_with
std::string str_value = /* smthg */;
const auto starts_with_foo = str_value.starts_with(std::string_view{"foo"});
In C++20 now there is starts_with available as a member function of std::string defined as:
constexpr bool starts_with(string_view sv) const noexcept;
constexpr bool starts_with(CharT c) const noexcept;
constexpr bool starts_with(const CharT* s) const;
So your code could be something like this:
std::string s{argv[1]};
if (s.starts_with("--foo="))
In case you need C++11 compatibility and cannot use boost, here is a boost-compatible drop-in with an example of usage:
#include <iostream>
#include <string>
static bool starts_with(const std::string str, const std::string prefix)
{
return ((prefix.size() <= str.size()) && std::equal(prefix.begin(), prefix.end(), str.begin()));
}
int main(int argc, char* argv[])
{
bool usage = false;
unsigned int foos = 0; // default number of foos if no parameter was supplied
if (argc > 1)
{
const std::string fParamPrefix = "-f="; // shorthand for foo
const std::string fooParamPrefix = "--foo=";
for (unsigned int i = 1; i < argc; ++i)
{
const std::string arg = argv[i];
try
{
if ((arg == "-h") || (arg == "--help"))
{
usage = true;
} else if (starts_with(arg, fParamPrefix)) {
foos = std::stoul(arg.substr(fParamPrefix.size()));
} else if (starts_with(arg, fooParamPrefix)) {
foos = std::stoul(arg.substr(fooParamPrefix.size()));
}
} catch (std::exception& e) {
std::cerr << "Invalid parameter: " << argv[i] << std::endl << std::endl;
usage = true;
}
}
}
if (usage)
{
std::cerr << "Usage: " << argv[0] << " [OPTION]..." << std::endl;
std::cerr << "Example program for parameter parsing." << std::endl << std::endl;
std::cerr << " -f, --foo=N use N foos (optional)" << std::endl;
return 1;
}
std::cerr << "number of foos given: " << foos << std::endl;
}
Why not use gnu getopts? Here's a basic example (without safety checks):
#include <getopt.h>
#include <stdio.h>
int main(int argc, char** argv)
{
option long_options[] = {
{"foo", required_argument, 0, 0},
{0,0,0,0}
};
getopt_long(argc, argv, "f:", long_options, 0);
printf("%s\n", optarg);
}
For the following command:
$ ./a.out --foo=33
You will get
33
Ok why the complicated use of libraries and stuff? C++ String objects overload the [] operator, so you can just compare chars.. Like what I just did, because I want to list all files in a directory and ignore invisible files and the .. and . pseudofiles.
while ((ep = readdir(dp)))
{
string s(ep->d_name);
if (!(s[0] == '.')) // Omit invisible files and .. or .
files.push_back(s);
}
It's that simple..
You can also use strstr:
if (strstr(str, substr) == substr) {
// 'str' starts with 'substr'
}
but I think it's good only for short strings because it has to loop through the whole string when the string doesn't actually start with 'substr'.
With C++11 or higher you can use find() and find_first_of()
Example using find to find a single char:
#include <string>
std::string name = "Aaah";
size_t found_index = name.find('a');
if (found_index != std::string::npos) {
// Found string containing 'a'
}
Example using find to find a full string & starting from position 5:
std::string name = "Aaah";
size_t found_index = name.find('h', 3);
if (found_index != std::string::npos) {
// Found string containing 'h'
}
Example using the find_first_of() and only the first char, to search at the start only:
std::string name = ".hidden._di.r";
size_t found_index = name.find_first_of('.');
if (found_index == 0) {
// Found '.' at first position in string
}
More about find
More about find_first_of
Good luck!
std::string text = "--foo=98";
std::string start = "--foo=";
if (text.find(start) == 0)
{
int n = stoi(text.substr(start.length()));
std::cout << n << std::endl;
}
Since C++11 std::regex_search can also be used to provide even more complex expressions matching. The following example handles also floating numbers thorugh std::stof and a subsequent cast to int.
However the parseInt method shown below could throw a std::invalid_argument exception if the prefix is not matched; this can be easily adapted depending on the given application:
#include <iostream>
#include <regex>
int parseInt(const std::string &str, const std::string &prefix) {
std::smatch match;
std::regex_search(str, match, std::regex("^" + prefix + "([+-]?(?=\\.?\\d)\\d*(?:\\.\\d*)?(?:[Ee][+-]?\\d+)?)$"));
return std::stof(match[1]);
}
int main() {
std::cout << parseInt("foo=13.3", "foo=") << std::endl;
std::cout << parseInt("foo=-.9", "foo=") << std::endl;
std::cout << parseInt("foo=+13.3", "foo=") << std::endl;
std::cout << parseInt("foo=-0.133", "foo=") << std::endl;
std::cout << parseInt("foo=+00123456", "foo=") << std::endl;
std::cout << parseInt("foo=-06.12e+3", "foo=") << std::endl;
// throw std::invalid_argument
// std::cout << parseInt("foo=1", "bar=") << std::endl;
return 0;
}
The kind of magic of the regex pattern is well detailed in the following answer.
EDIT: the previous answer did not performed the conversion to integer.
if(boost::starts_with(string_to_search, string_to_look_for))
intval = boost::lexical_cast<int>(string_to_search.substr(string_to_look_for.length()));
This is completely untested. The principle is the same as the Python one. Requires Boost.StringAlgo and Boost.LexicalCast.
Check if the string starts with the other string, and then get the substring ('slice') of the first string and convert it using lexical cast.