I'm looking for the best way to remove the first word from a std::string. This is what I have but I feel that this is overcompilicating things. What's the best and shortest way to do this? Thanks.
#include <string>
#include <iostream>
#include <sstream>
int main()
{
std::string str{"Where is everybody?"};
std::string first;
if (std::stringstream{str} >> first)
{
str.erase(str.begin(), str.begin() + first.size());
}
std::cout << str; // " is everybody?"
}
minor tweak, that leverages IO streams for the second half too :)
#include <string>
#include <iostream>
#include <sstream>
int main()
{
std::string str{"Where is everybody?"};
std::string first;
std::istringstream iss{str};
iss >> first;
std::ostringstream oss;
oss << iss.rdbuf();
std::cout << oss.str(); // " is everybody?"
}
You can do it without a stream: skip the initial spaces, locate the first space after that, walk to the next non-space, and use substr to get the rest of the string:
int i = 0;
while (isblank(str[i])) i++;
while (!isblank(str[i])) i++;
while (isblank(str[i])) i++;
str = str.substr(i);
Here is a demo on ideone.
Here is a solution using c++11's regex
#include <iostream>
#include <string>
#include <regex>
#include <iterator>
int main ()
{
std::string s ("there is a subsequence in the string\n");
std::regex e ("(\\s*)(\\w*)(.*)");
std::cout << std::regex_replace (s,e,"$1$3");
return 0;
}
You could try using string::substr() and string::find_first_of().
Related
How would I get the last part of a URL?
Say the variable url is https://somewhere.com/stuff/hello.
How would I get hello from this?
Using rfind and substr
Maybe with
#include <iostream>
#include <string>
int main() {
std::string url{"https://somewhere.com/stuff/hello"};
std::cout << url.substr(url.rfind('/')+1);
return 0;
}
But only, if you have a / in front of the last part
#include <iostream>
#include <string>
int main() {
const std::string url("https://somewhere.com/stuff/hello");
const std::size_t indexLastSeparator = url.find_last_of("/");
if (indexLastSeparator != std::string::npos)
{
const std::string lastPartUrl = url.substr(indexLastSeparator+1); // +1 to not keep /
std::cout << lastPartUrl << '\n'; // print "hello"
}
}
With find_last_of() and substr()
references :
https://en.cppreference.com/w/cpp/string/basic_string/find_last_of
https://en.cppreference.com/w/cpp/string/basic_string/substr
I have some string :
testing testing
test2test2
these lines are devided by CRLF. I saw that there are : 0d0a0d0a deviding them.
How can I split it using this information?
I wanted to use str.find(CRLF-DELIMITER) but can't semm to figure how
editing :
I already used str.find("textDelimiter"), but now I need it to look for hexa and not search for a string "0d0a0d0a"
Use boost::split to do that. Please also take a look at Boost.Tokenizer.
Here is another way of doing it using regex:
using std::endl;
using std::cout;
using std::string;
using std::vector;
using boost::algorithm::split_regex;
int main()
{
vector<string> res;
string input = "test1\r\ntest2\r\ntest3";
split_regex(res, input, boost::regex("(\r\n)+"));
for (auto& tok : res)
{
std::cout << "Token: " << tok << std::endl;
}
return 0;
}
Here is the way of doing it without Boost:
#include <string>
#include <sstream>
#include <istream>
#include <vector>
#include <iostream>
int main()
{
std::string strlist("line1\r\nLine2\r\nLine3\r\n");
std::istringstream MyStream(strlist);
std::vector<std::string> v;
std::string s;
while (std::getline(MyStream, s))
{
v.push_back(s);
std::cout << s << std::endl;
}
return 0;
}
The best I can come up with is:
#include <boost/algorithm/string/replace.hpp>
#include <boost/regex.hpp>
#include <iostream>
using namespace std;
int main() {
string dog = "scooby-doo";
boost::regex pattern("(\\w+)-doo");
boost::smatch groups;
if (boost::regex_match(dog, groups, pattern))
boost::replace_all(dog, string(groups[1]), "scrappy");
cout << dog << endl;
}
with output:
scrappy-doo
.. is there a simpler way of doing this, that doesn't involve doing two distinct searches? Maybe with the new C++11 stuff (although I'm not sure that it's compatible with gcc atm?)
std::regex_replace should do the trick. The provided example is pretty close to your problem, even to the point of showing how to shove the answer straight into cout if you want. Pasted here for posterity:
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
int main()
{
std::string text = "Quick brown fox";
std::regex vowel_re("a|e|i|o|u");
// write the results to an output iterator
std::regex_replace(std::ostreambuf_iterator<char>(std::cout),
text.begin(), text.end(), vowel_re, "*");
// construct a string holding the results
std::cout << '\n' << std::regex_replace(text, vowel_re, "[$&]") << '\n';
}
I am trying to make a simple piece of code work with boost::is_any_of and boost::replace_all_copy. The snippet is below:
std::string someString = "abc.def-ghi";
std::string toReplace = ".-";
std::string processedString = boost::replace_all_copy(someString, boost::is_any_of(toReplace), " ");
However, I get a compiler error that is too long to paste here. Could someone that has experience with these 2 functions please point out my error?
I don't think you can't. The three parameter version of boost::replace_all_copy takes the input string, a substitute string and the string to search for. What boost::is_any_of returns is a predicate functor.
What you probably want is boost::replace_if:
#include <boost/algorithm/string.hpp> // for is_any_of
#include <boost/range/algorithm/replace_if.hpp> // for replace_if
#include <string>
#include <iostream>
std::string someString = "abc.def-ghi";
std::string toReplace = ".-";
std::string processedString =
boost::replace_if(someString, boost::is_any_of(toReplace), ' ');
int main()
{
std::cout << processedString;
}
This modifies the original, so if you need to keep it, you can use boost::replace_copy_if:
#include <boost/algorithm/string.hpp>
#include <boost/range/algorithm/replace_copy_if.hpp>
#include <string>
#include <iostream>
#include <iterator> // for back_inserter
std::string someString = "abc.def-ghi";
std::string toReplace = ".-";
int main()
{
std::string processedString;
boost::replace_copy_if(someString,
std::back_inserter(processedString), boost::is_any_of(toReplace), ' ');
std::cout << processedString;
}
Hope that helps.
I am not overly familiar with that particular method but it appears that replace_all_copy wants just a replacement string rather than the result of is_any_of.
Glancing through the other options for string algorithms I noticed that there is a regex version that would also work:
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
int main(int argc, char** argv) {
std::string someString = "abc.def-ghi";
std::cout << someString << std::endl;
std::string toReplace = "[.-]"; // character class that matches . and -
std::string replacement = " ";
std::string processedString =
boost::replace_all_regex_copy(someString, boost::regex(toReplace), replacement);
std::cout << processedString << std::endl;
return 0;
}
Output:
abc.def-ghi
abc def ghi
This does require linking against the boost regex lib. In my case, I built with:
g++ -L/usr/local/Cellar/boost/1.52.0/lib -lboost_regex-mt main.cpp
I want to join a vector<string> into a single string, separated by spaces. For example,
sample
string
for
this
example
should become "sample string for this example".
What is the simplest way to do this?
#include <iterator>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
std::vector<std::string> v;
...
std::stringstream ss;
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(ss, " "));
std::string result = ss.str();
if (!result.empty()) {
result.resize(result.length() - 1); // trim trailing space
}
std::cout << result << std::endl;
boost::join