Parsing a C++ string in C++ - c++

I have a requirement like this: I have a string like "-myArg:ArgVal".
std::string strArg = "-myArg:ArgVal";
Now, I have to check in above string first character is always '-' and if first character is '-' i should remove it and i should store "myArg" and "ArgVal" in two different string objects.
How can I do this efficiently?

Try this
if (strArg[0] == '-') {
strVar1 = strArg.substr(1, strArg.find(':') - 1);
strVar2 = strArg.substr(strArg.find(':') + 1);
}
Of course I'm assuming that if the string starts with '-' then there will be a ':' in it with chars before and after. You should probably check this because if there isn't it can cause an error

Have a look at std::string::substr() and std::string::find().

The most scalable and solid way is via regular expressions. Recommended library is Boost.Regex

std::string has the functions you need. You can check the first char by using string::at and create substrings with string::substr. Erasing single chars works the same comfortable way.
See a c++ reference for more information.

Related

How to return position of last char occurance?

I'm using WDL_String container to manage string within a C++ Framework. I need to split a string (delimiter \) and get the last occurrence.
I can use the native method:
mFilePath.DeleteSub(mLastOccPosition, mFilePath.GetLength());
subbing the string, but I don't know how to catch the mLastOccPosition.
So if I have this string:
D:\\Google Drive\\My Files\\Test.zip
I need to return Test.zip. What's the best way to do this in C++?
If s is an instance of std::string, then s.find_last_of('\\') would do it.
It returns std::string::npos if it can't be found.
You can then use std::string::substr to extract the bit you need.

C++ - Replace spaces with %20

I am looking for a way to prepare a string for use as a URL.
The basics of the code is you type in what you are looking for and it opens a browser with what you typed in. I am learning C++, so this is a learning program. And please be as specific as possible for I am new to C++.
Here is what I am trying to do:
cin >> s_input;
transform(s_input.begin(), s_input.end(), s_input.begin(), tolower);
s_input = "start http://website.com/" + s_input + "/0/7/0";
system(s_input.c_str());
But I am trying to replace all the spaces the user enter with a '%20'. I have found one method this way but it only works with one letter at a time, and I am needing to do it with a full string and not an array of chars. Here is the method I have tried:
cin >> s_input;
transform(s_input.begin(), s_input.end(), s_input.begin(), tolower);
using std::string;
using std::cout;
using std::endl;
using std::replace;
replace(s_input.begin(), s_input.end(), ' ', '%20');
s_input = "start http://website.com/" + s_input + "/0/7/0";
system(s_input.c_str());
Thanks for your help!
If you have Visual Studio 2010 or later you should be able to use regular expressions to search/replace:
std::regex space("[[:space:]]");
s_input = std::regex_replace(s_input, space, "%20");
Edit: How to use the six-argument version of std::regex_replace:
std::regex space("[[:space:]]");
std::string s_output;
std::regex_replace(s_output.begin(), s_input.begin(), s_input.end(), space, "%20");
The string s_output now contains the changed string.
You might have to change the replacement string to std::string("%20").
As you see I have only five arguments, that's because the sixth should have a default value.
std::replace is only able to replace single elements (chars in this case) with single elements. You are trying to replace a single element with three. You will need a special function to do that. Boost has one, called replace_all, you can use it like this:
boost::replace_all(s_input, " ", "%20");
If you google: C++ UrlEncode, you will find many hits. Here's one:
http://www.zedwood.com/article/111/cpp-urlencode-function

how to replace all instances of a sub string in a string

I'm trying to work with RegEx to split a large string into smaller sections, and as part of this I'm trying to replace all instances of a substring in this larger string. I've been trying to use the replace function but this only replaces the first instance of the substring. How can I replace al instances of the substring within the larger string?
Thanks
Stephen
adding 'g' to searchExp. e.g. /i_want_to_be_replaced/g
One fast way is use split and join:
function quickReplace(source:String, oldString:String, newString:String):String
{
return source.split(oldString).join(newString);
}
In addition to #Alex's answer, you might also find this answer handy,
using String's replace() method.
here's a snippet:
function addLinks(pattern:RegExp,text:String):String{
var result = '';
while(pattern.test(text)) result = text.replace(pattern, "<font color=\"#0000dd\">$&</font>");
if(result == '') result+= text;//if there was nothing to replace
return result;
}

How to replace a string between two substrings in a string in VC++/MFC?

Say I have a CString object strMain="AAAABBCCCCCCDDBBCCCCCCDDDAA";
I also have two smaller strings, say strSmall1="BB";
strSmall2="DD";
Now, I want to replace all occurence of strings which occur between strSmall1("BB") and strSmall2("DD") in strMain, with say "KKKKKKK"
Is there a way to do it without Regex. I cannot use regex as adding another file to the project is prohibited.
Is there a way in VC++/MFC to do it? Or any easy algorithm you can point me to?
int length = strMain.GetLength();
int begin = strMain.Find(strSmall1, 0) + strSmall1.GetLength();
int end = strMain.Find(strSmall2, 0);
CStringT left = strMain.Left(begin);
CStringT right = strMain.Right(length - end);
strMain = left + "KKKKKKK" + right
The easiest way is probably to handle the replacement recursively. Search for the starting delimiter and the ending delimiter. If you find them, put together a new string consisting of the string up to the starting delimiter, followed by the replacement string, followed by the return from recursively doing the replacement in the remainder of the string following the ending delimiter.
That, of course, assumes you want to replace all the occurrences in the main string -- if you only want to replace the first one, John Weldon's solution (for one example) will work quite nicely.
psudocode:
loop over string
if curlocation matches string strsmall1 save index break
loop over remaining string
replace till curlocation matches string strsmall2
Extra credit:
What will the next assignment be?
My answer:
Speed it up by jumping the length of strsmall1 and strsmall2 in loop iterations

Regex - If contains '%', can only contain '%20'

I am wanting to create a regular expression for the following scenario:
If a string contains the percentage character (%) then it can only contain the following: %20, and cannot be preceded by another '%'.
So if there was for instance, %25 it would be rejected. For instance, the following string would be valid:
http://www.test.com/?&Name=My%20Name%20Is%20Vader
But these would fail:
http://www.test.com/?&Name=My%20Name%20Is%20VadersAccountant%25
%%%25
Any help would be greatly appreciated,
Kyle
EDIT:
The scenario in a nutshell is that a link is written to an encoded state and then launched via JavaScript. No decoding works. I tried .net decoding and JS decoding, each having the same result - The results stay encoded when executed.
Doesn't require a %:
/^[^%]*(%20[^%]*)*$/
Which language are you using?
Most languages have a Uri Encoder / Decoder function or class.
I would suggest you decode the string first and than check for valid (or invalid) characters.
i.e. something like /[\w ]/ (empty is a space)
With a regex in the first place you need to respect that www.example.com/index.html?user=admin&pass=%%250 means that the pass really is "%250".
Another solution if look-arounds are not available:
^([^%]|%([013-9a-fA-F][0-9a-fA-F]|2[1-9a-fA-F]))*$
Reject the string if it matches %[^2][^0]
I think that would find what you need
/^([^%]|%%|%20)+$/
Edit: Added case where %% is valid string inside URI
Edit2: And fixed it for case where it should fail :-)
Edit3:
In case you need to use it in editor (which would explain why you can't use more programmatic way), then you have to correctly escape all special characters, for example in Vim that regex should lool:
/^\([^%]\|%%\|%20\)\+$/
Maybe a better approach is to deal with that validation after you decode that string:
string name = HttpUtility.UrlDecode(Request.QueryString["Name"]);
/^([^%]|%20)*$/
This requires a test against the "bad" patterns. If we're allowing %20 - we don't need to make sure it exists.
As others have said before, %% is valid too... and %%25would be %25
The below regex matches anything that doesn't fit into the above rules
/(?<![^%]%)%(?!(20|%))/
The first brackets check whether there is a % before the character (meaning that it's %%) and also checks that it's not %%%. it then checks for a %, and checks whether the item after doesn't match 20
This means that if anything is identified by the regex, then you should probably reject it.
I agree with dominic's comment on the question. Don't use Regex.
If you want to avoid scanning the string twice, you can just iteratively search for % and then check that it is being followed by 20 and nothing else. (Update: allow a % after to be interpreted as a literal %nnn sequence)
// pseudo code
pos = 0
while (pos = mystring.find(pos, '%'))
{
if mystring[pos+1] = "%" then
pos = pos + 2 // ok, this is a literal, skip ahead
else if mystring.substring(pos,2) != "20"
return false; // string is invalid
end if
}
return true;