Error "no match for 'operator+" when concatenating strings - c++

I am trying to reverse the words in a string using this code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
//_ _ the sky is blue
string vec;
getline(cin, vec);
stack<string> str;
string temp = "";
string ans = "";
for (int i = 0; i < vec.length(); i++)
{
if (vec.at(i) == ' ')
{
if (temp.length() > 0)
{
str.push(temp);
temp = "";
}
else
{
temp = temp + vec.at(i);
}
}
}
//ans = ans + temp;
while (!str.empty())
{
ans = ans + " " + str.pop();
}
if (ans.length() != 0 && ans.at(0) == ' ')
ans = ans.substr(1);
cout << ans << endl;
}
I'm receiving this error at line 33 telling "no match for 'operator+'".
I have attached the relevant screenshot:
Please, help.

pop() is a stack member method with void return type, it doesn't return a string, therefore it cannot be printed neither can it be concatenated with other strings.
As the error shows you you can't add void and string using + operator for these 2 different types (unless you made that option available by overloading the + operator), so ans = ans + " " + str.pop(); is wrong.
You could use:
while (!str.empty())
{
ans = ans + " " + str.top();
str.pop();
}
As top() does return a string object.
I should point out that using #include <bits/stdc++.h> is bad and using namespace std is also not very good, but bringing them together is a disaster waiting to happen.

The method pop of the container adapter std::stack has the return type void. So this statement
ans= ans+" "+str.pop();
is incorrect and the compiler will issue an error.
You need to write something like
while(!str.empty()){
ans= ans+" "+ str.top();
str.pop();
}
Pay attention to that this for loop
for(int i=0 ; i<vec.length(); i++){
if(vec.at(i)==' '){
if(temp.length()>0){
str.push(temp);
temp = "";
}
else{
temp = temp + vec.at(i);
}
}
}
has a bug. If the string stored in the object vec does not end with a space character then the last word of the string will not be pushed on the stack.
It seems what you are trying to do is the following.
#include <iostream>
#include <string>
#include <stack>
#include <cctype>
int main()
{
std::string s( " Hello World " );
std::stack<std::string> st;
std::cout << "\"" << s << "\"\n";
for ( std::string::size_type i = 0; i < s.size(); )
{
std::string tmp;
while ( i < s.size() && isspace( ( unsigned char )s[i] ) )
{
tmp += s[i++];
}
if ( !tmp.empty() )
{
st.push( tmp );
tmp.clear();
}
while ( i < s.size() && !isspace( ( unsigned char )s[i] ) )
{
tmp += s[i++];
}
if ( !tmp.empty() )
{
st.push( tmp );
}
}
std::string result;
while ( !st.empty() )
{
result += st.top();
st.pop();
}
std::cout << "\"" << result << "\"\n";
return 0;
}
The program output is
" Hello World "
" World Hello "

Thank you guys for helping me out. Here's code and working perfectly fine:
#include <bits/stdc++.h>
using namespace std;
int main(){
//_ _ the sky is blue
string vec;
getline(cin, vec);
stack<string>str;
string rs;
string temp="";
string ans= "";
for(int i=0 ; i<vec.length(); i++){
if(vec.at(i)==' '){
if(temp.length()>0){
str.push(temp);
temp = "";
}
}
else{
temp = temp + vec.at(i);
}
}
ans = ans + temp;
while(!str.empty()){
ans= ans+" "+str.top();
str.pop();
}
if(ans.length() != 0 && ans.at(0) == ' '){
ans = ans.substr(1);
}
cout<<ans<<endl;
reverse( ans.begin(), ans.end());
cout<<ans<<endl;
}
Here is the output which only allows single space between each words and eliminates both leading and trailing space:

Related

Replace every occurrence with double in string

I'm trying to write a function whose first parameter is a string and the second parameter is vector of real numbers. The function should return as a result a new string in which each occurrence replaces the sequences "%d" or "%f" with one number each from the vector, in the order in which they appear. In doing so, if the sequence is "%d", any decimals in the number are truncated, while in the sequence "%f" they are retained.
For example, if the string reads “abc%dxx%fyy %d” and if the vector contains the numbers 12.25, 34.13, 25 and 47, the new string should read “abc12xx34.13yy 25” (data 47 which is “redundant” is simply ignored).
#include <iostream>
#include <string>
#include <vector>
std::string Replace(std::string s, std::vector < double > vek) {
std::string str;
int j = 0;
for (int i = 0; i < s.length(); i++) {
while (s[i] != '%' && i < s.length()) {
if (s[i] != 'f' && s[i] != 'd')
str += s[i];
i++;
}
if (s[i] == '%' && (s[i + 1] == 'd' || s[i + 1] == 'f')) {
if (s[i + 1] == 'd')
str += (std::to_string(int(vek[j])));
if (s[i + 1] == 'f') {
std::string temp = std::to_string(vek[j]);
int l = 0;
while (temp[l] != '0') {
str += temp[l];
l++;
}
}
j++;
if (j > vek.size())
throw std::range_error("Not enough elements");
if (i == s.length()) break;
}
}
return str;
}
int main() {
try {
std::cout<<Replace("abc%dxx%fyy %d",{12.25, 34.13, 25});
std::cout << "\n" << "abc12xx34.13yy 25";
} catch (std::range_error e) {
std::cout << e.what();
}
return 0;
}
OUTPUT:
abc12xx34.13yy 25
abc12xx34.13yy 25
Output is correct. How could I modify this to work with less lines of code? Is there any way to make this more elegant and efficient?
You could use:
regular expressions to search for the pattern (%d|%f), i.e., %d or %f, and
a string stream to create the string to return.
Going into some more detail:
The code is basically a while (std::regex_search).
std::regex_search will return whatever was in the input string before the matched pattern (what you want in the output string), the matched pattern (what you will need to check in order to decide if you want to write out an int or a double), and whatever is left to parse.
By using std::ostringstream, you can simply write out ints or doubles without converting them to strings yourself.
vek.at() will throw an std::out_of_range exception if you run out of data in the vector.
Notice as well that, whereas for this implementation it's good to pass the string s by value (since we are modifying it within the function), you should pass vek as a const reference to avoid a copy of the whole vector.
[Demo]
#include <iostream>
#include <regex>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>
std::string Replace(std::string s, const std::vector<double>& vek) {
std::regex pattern{"(%d|%f)"};
std::smatch match{};
std::ostringstream oss{};
for (auto i{0}; std::regex_search(s, match, pattern); ++i) {
oss << match.prefix();
auto d{vek.at(i)};
oss << ((match[0] == "%d") ? static_cast<int>(d) : d);
s = match.suffix();
}
return oss.str();
}
int main() {
try {
std::cout << Replace("abc%dxx%fyy %d", {12.25, 34.13, 25});
std::cout << "\n"
<< "abc12xx34.13yy 25";
} catch (std::out_of_range& e) {
std::cout << e.what();
}
}
// Outputs:
//
// abc12xx34.13yy 25
// abc12xx34.13yy 25
[EDIT] A possible way to do it without std::regex_search would be to search for the (%d|%f) pattern manually, using std::string::find in a loop until the end of the string is reached.
The code below takes into account that:
the input string could not have that pattern, and that
it could have a % character followed by neither d nor f.
[Demo]
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
std::string Replace(std::string s, const std::vector<double>& vek) {
std::ostringstream oss{};
size_t previous_pos{0};
size_t pos{0};
auto i{0};
while (previous_pos != s.size()) {
if ((pos = s.find('%', previous_pos)) == std::string::npos) {
oss << s.substr(previous_pos);
break;
}
oss << s.substr(previous_pos, pos - previous_pos);
bool pattern_found{false};
if (s.size() > pos + 1) {
auto c{s[pos + 1]};
if (c == 'd') {
oss << static_cast<int>(vek.at(i));
pattern_found = true;
} else if (c == 'f') {
oss << vek.at(i);
pattern_found = true;
}
}
if (pattern_found) {
++i;
previous_pos = pos + 2;
} else {
oss << s[pos];
previous_pos = pos + 1;
}
}
return oss.str();
}
int main() {
try {
std::cout << Replace("abc%%dx%x%fyy %d", {12.25, 34.13, 25}) << "\n";
std::cout << "abc%12x%x34.13yy 25\n";
std::cout << Replace("abcdxxfyy d", {12.25, 34.13, 25}) << "\n";
std::cout << "abcdxxfyy d\n";
} catch (std::out_of_range& e) {
std::cout << e.what();
}
}
// Outputs:
//
// abc%12x%x34.13yy 25
// abc%12x%x34.13yy 25
// abcdxxfyy d
// abcdxxfyy d
#include <iostream>
#include <vector>
#include <string>
std::string replace(std::string str, std::vector<double> vec) {
std::string result = "";
int i = 0;
// loop through the string
while (i < str.size()) {
// if the current character is a %
if (str[i] == '%') {
// if the next character is a d
if (str[i+1] == 'd') {
// if the vector is not empty
if (vec.size() > 0) {
// add the first element of the vector to the result
result += std::to_string(vec[0]);
// remove the first element of the vector
vec.erase(vec.begin());
}
// move the index to the next character
i += 2;
}
// if the next character is a f
else if (str[i+1] == 'f') {
// if the vector is not empty
if (vec.size() > 0) {
// add the first element of the vector to the result
result += std::to_string(vec[0]);
// remove the first element of the vector
vec.erase(vec.begin());
}
// move the index to the next character
i += 2;
}
// if the next character is not a d or f
else {
// add the current character to the result
result += str[i];
// move the index to the next character
i += 1;
}
}
// if the current character is not a %
else {
// add the current character to the result
result += str[i];
// move the index to the next character
i += 1;
}
}
// return the result
return result;
}
int main() {
std::vector<double> vec = {12.25, 34.13, 25, 47};
std::string str = "abc%dxx%fyy %d";
std::cout << replace(str, vec);
return 0;
}

How do I find the size of a char array?

How should I go about finding the length of a char array in C++? I've tried two methods already, but they both have resulted in the wrong number of characters in the array. I've used strlen and the sizeof operator so far, to no avail.
void countOccurences(char *str, string word)
{
char *p;
string t = "true";
string f = "false";
vector<string> a;
p = strtok(str, " ");
while (p != NULL)
{
a.push_back(p);
p = strtok(NULL, " ");
}
int c = 0;
for (int i = 0; i < a.size(); i++)
{
if (word == a[i])
{
c++;
}
}
int length = sizeof(str); //This is where I'm having the problem
string result;
cout << length << "\n";
if (length % 2 != 0)
{
if (c % 2 == 0)
{
result = "False";
}
else
{
result = "True";
}
}
else
{
if (c % 2 == 0)
{
result = "True";
}
else
{
result = "False";
}
}
if (strlen(str) != 0)
{
cout << result;
}
}
int boolean()
{
char str[1000];
cin.getline(str, sizeof(str));
string word = "not";
countOccurences(str, word);
return 0;
}
sizeof(str) is wrong. It gives you the size of a pointer (str is a pointer), which is a fixed number, normally either 4 or 8 depending at your platform.
std::strlen(str) is correct, but strtok inserts a bunch of \0 into your array before you try to obtain the size. strlen will stop at the first \0, and give you the number of characters preceeding it.
Call strlen before strtok and save its return value to a variable.
Here you can find a modern c++ solution:
#include <iostream>
#include <string_view>
#include <string>
#include <type_traits>
template<typename String>
inline std::size_t StrLength(String&& str)
{
using PureString = std::remove_reference_t<std::remove_const_t<String>>;
if constexpr(std::is_same_v<char, PureString>){
return 1;
}
else
if constexpr(std::is_same_v<char*, PureString>){
return strlen(str);
}
else{
return str.length();
}
}
template<
typename String,
typename Lambda,
typename Delim = char
>
void ForEachWord(String&& str, Lambda&& lambda, Delim&& delim = ' ')
{
using PureStr = std::remove_reference_t<std::remove_reference_t<String>>;
using View = std::basic_string_view<typename PureStr::value_type>;
auto start = 0;
auto view = View(str);
while(true)
{
auto wordEndPos = view.find_first_of(delim, start);
auto word = view.substr(start, wordEndPos-start);
if (word.length() > 0){
lambda(word);
}
if (wordEndPos == PureStr::npos)
{
break;
}
start = wordEndPos + StrLength(delim);
}
}
int main() {
std::string text = "This is not a good sentence.";
auto cnt = 0;
ForEachWord(
text,
[&](auto word)
{
//some code for every word... like counting or printing
if (word == "not" ){
++cnt;
}
},
' '
);
std::cout << cnt << "\n";
}
The "end of a string" is the char '\0' check for that character to stop the search.

How to insert an integer with leading zeros into a std::string?

In a C++14 program, I am given a string like
std::string s = "MyFile####.mp4";
and an integer 0 to a few hundred. (It'll never be a thousand or more, but four digits just in case.) I want to replace the "####" with the integer value, with leading zeros as needed to match the number of '#' characters. What is the slick C++11/14 way to modify s or produce a new string like that?
Normally I would use char* strings and snprintf(), strchr() to find the "#", but figure I should get with modern times and use std::string more often, but know only the simplest uses of it.
What is the slick C++11/14 way to modify s or produce a new string like that?
I don't know if it's slick enough but I propose the use of std::transform(), a lambda function and reverse iterators.
Something like
#include <string>
#include <iostream>
#include <algorithm>
int main ()
{
std::string str { "MyFile####.mp4" };
int num { 742 };
std::transform(str.rbegin(), str.rend(), str.rbegin(),
[&](auto ch)
{
if ( '#' == ch )
{
ch = "0123456789"[num % 10]; // or '0' + num % 10;
num /= 10;
}
return ch;
} // end of lambda function passed in as a parameter
); // end of std::transform()
std::cout << str << std::endl; // print MyFile0742.mp4
}
I would use regex since you're using C++14:
#include <iostream>
#include <regex>
#include <string>
#include <iterator>
int main()
{
std::string text = "Myfile####.mp4";
std::regex re("####");
int num = 252;
//convert int to string and add appropriate number of 0's
std::string nu = std::to_string(num);
while(nu.length() < 4) {
nu = "0" + nu;
}
//let regex_replace do it's work
std::regex_replace(std::ostreambuf_iterator<char>(std::cout),
text.begin(), text.end(), re, nu);
std::cout << std::endl;
return 0;
}
WHy not use std::stringstream and than convert it to string.
std::string inputNumber (std::string s, int n) {
std::stringstream sstream;
bool numberIsSet = false;
for (int i = 0; i < s; ++i) {
if (s[i] == '#' && numberIsSet == true)
continue;
else if (s[i] == '#' && numberIsSet == false) {
sstream << setfill('0') << setw(5) << n;
numberIsSet = true;
} else
sstream << s[i];
}
return sstream.str();
}
I would probably use something like this
#include <iostream>
using namespace std;
int main()
{
int SomeNumber = 42;
std:string num = std::to_string(SomeNumber);
string padding = "";
while(padding.length()+num.length()<4){
padding += "0";
}
string result = "MyFile"+padding+num+".mp4";
cout << result << endl;
return 0;
}
Mine got out of control while I was playing with it, heh.
Pass it patterns on its command line, like:
./cpp-string-fill file########.jpg '####' test###this### and#this
#include <string>
#include <iostream>
#include <sstream>
std::string fill_pattern(std::string p, int num) {
size_t start_i, end_i;
for(
start_i = p.find_first_of('#'), end_i = start_i;
end_i < p.length() && p[end_i] == '#';
++end_i
) {
// Nothing special here.
}
if(end_i <= p.length()) {
std::ostringstream os;
os << num;
const std::string &ns = os.str();
size_t n_i = ns.length();
while(end_i > start_i && n_i > 0) {
end_i--;
n_i--;
p[end_i] = ns[n_i];
}
while(end_i > start_i) {
end_i--;
p[end_i] = '0';
}
}
return p;
}
int main(int argc, char *argv[]) {
if(argc<2) {
exit(1);
}
for(int i = 1; i < argc; i++) {
std::cout << fill_pattern(argv[i], 1283) << std::endl;
}
return 0;
}
I would probably do something like this:
using namespace std;
#include <iostream>
#include <string>
int main()
{
int SomeNumber = 42;
string num = std::to_string(SomeNumber);
string guide = "myfile####.mp3";
int start = static_cast<int>(guide.find_first_of("#"));
int end = static_cast<int>(guide.find_last_of("#"));
int used = 1;
int place = end;
char padding = '0';
while(place >= start){
if(used>num.length()){
guide.begin()[place]=padding;
}else{
guide.begin()[place]=num[num.length()-used];
}
place--;
used++;
}
cout << guide << endl;
return 0;
}

Taking Each Individual Word From a String in C++

I am writing a method in C++ which will take a string of 2 or more words and output each individual word of the string separated by a second or so, using the sleep() method. I am trying to do this using a for loop and substrings. I am unsure also of the regexs which should be used, and how they should be used, to achieve the desired output.
I have reviewed this and this and find my question differs since I am trying to do this in a loop, and not store the individual substrings.
Input:
"This is an example"
Desired output:
"This " (pause) "is " (pause) "an " (pause) "example."
Use std::stringstream, no regular expressions required:
#include <iostream>
#include <sstream>
using namespace std;
int main() {
stringstream ss("This is a test");
string s;
while (ss >> s) {
cout << s << endl;
}
return 0;
}
Also, see How do I tokenize a string in C++?
Here are a pair of implementations that don't involve creating any extraneous buffers.
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp> //for boost::copy
#include <chrono>
#include <iostream>
#include <string>
#include <experimental/string_view> //in clang or gcc; or use boost::string_ref in boost 1.53 or later; or use boost::iterator_range<char*> in earlier version of boost
#include <thread>
void method_one(std::experimental::string_view sv)
{
for(auto b = sv.begin(), e = sv.end(), space = std::find(b, e, ' ')
; b < e
; b = space + 1, space = std::find(space + 1, e, ' '))
{
std::copy(b, space, std::ostreambuf_iterator<char>(std::cout));
std::cout << " (pause) "; //note that this will spit out an extra pause the last time through
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void method_two(std::experimental::string_view sv)
{
boost::copy(
sv | boost::adaptors::filtered([](const char c) -> bool
{
if(c == ' ')
{
std::cout << " (pause) "; //note that this spits out exactly one pause per space character
std::this_thread::sleep_for(std::chrono::seconds(1));
return false;
}
return true;
})
, std::ostreambuf_iterator<char>(std::cout)
);
}
int main() {
const std::string s{"This is a string"};
method_one(s);
std::cout << std::endl;
method_two(s);
std::cout << std::endl;
return 0;
}
Live on coliru, if you're into that.
you can implement your own method:
//StrParse.h
#pragma once
#include <iostream>
static counter = 0;
char* strPar(char* pTxt, char c)
{
int lenAll = strlen(pTxt);
bool strBeg = false;
int nWords = 0;
for(int i(0); i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
i++;
}
if(strBeg)
{
nWords++;
strBeg = false;
}
}
int* pLens = new int[nWords];
int j = 0;
int len = 0;
for(i = 0; i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
i++;
len++;
}
if(strBeg)
{
pLens[j] = len;
j++;
strBeg = false;
len = 0;
}
}
char** pStr = new char*[nWords + 1];
for(i = 0; i < nWords; i++)
pStr[i] = new char[pLens[i] + 1];
int k = 0, l = 0;
for(i = 0; i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
pStr[k][l] = pTxt[i];
l++;
i++;
}
if(strBeg)
{
pStr[k][l] = '\0';
k++;
l = 0;
strBeg = false;
}
}
counter++;
if(counter <= nWords)
return pStr[counter - 1];
else
return NULL;
}
//main.cpp
#include "StrParse.h"
void main()
{
char* pTxt = " -CPlusPlus -programming -is -a - superb thing ";
char* pStr1 = NULL;
int i = 1;
char sep;
std::cout << "Separator: ";
sep = std::cin.get();
std::cin.sync();
while(pStr1 = strPar(pTxt, sep))
{
std::cout << "String " << i << ": " << pStr1 << std::endl;
delete pStr1;
i++;
}
std::cout << std::endl;
}

splitting string into vector c++

I wrote a simple code to split the string from each '/' and store into vector.
My string may start with / or not and definetelly will end with /. For example if my string is:
string="/home/desktop/test/"
I want to <"/","home","desktop","test"> and another example
string="../folder1/folder2/../pic.pdf/"
I want to store <"..","folder1","folder2","..","pic.pdf"
However, my code gives me <" ","home","desktop","test"," "> for the first example and
<"..","folder1","folder2","..","pic.pdf"," "> for the second example
Is there anyone to help me ?
Here is my code for this :
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string strLine("/cd/desktop/../test/");
string strTempString;
vector<int> splitIndices;
vector<string> splitLine;
int nCharIndex = 0;
int nLineSize = strLine.size();
// find indices
for(int i = 0; i < nLineSize; i++)
{
if(strLine[i] == '/')
splitIndices.push_back(i);
}
splitIndices.push_back(nLineSize); // end index
// fill split lines
for(int i = 0; i < (int)splitIndices.size(); i++)
{
strTempString = strLine.substr(nCharIndex, (splitIndices[i] - nCharIndex));
splitLine.push_back(strTempString);
cout << strTempString << endl;
nCharIndex = splitIndices[i] + 1;
}
}
The C++ String Toolkit Library (Strtk) has the following solution to your problem:
http://www.codeproject.com/Articles/23198/C-String-Toolkit-StrTk-Tokenizer
Some things to do in the code that should fix this, there might be a better and more elegant solution for this.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string strLine("/cd/desktop/../test/");
string strTempString;
vector<int> splitIndices;
vector<string> splitLine;
int nCharIndex = 0;
int nLineSize = strLine.size();
// find indices
if(nLineSize!=0 && strLine[0]=='/')
{
splitLine.push_back(strLine.substr(0,1));
nCharIndex++;
}
for(int i = 1; i < nLineSize; i++)
{
if(strLine[i] == '/')
splitIndices.push_back(i);
}
// fill split lines
for(int i = 0; i <int(splitIndices.size()); i++)
{
strTempString = strLine.substr(nCharIndex, (splitIndices[i] - nCharIndex));
splitLine.push_back(strTempString);
nCharIndex = splitIndices[i] + 1;
}
}
Edit :
Cleaned the code a bit, you can remove the adding the last index part now.
Edit 2:
A possibly more elegant looking solution for this might be by removing the ncharcounter and using your splitting index for that. You can store the first value as '-1' if the first character is not ('/') or as ('0') if it is.
string strLine("/cd/desktop/../test/");
string strTempString;
vector<int> splitIndices;
vector<string> splitLine;
int nLineSize = strLine.size();
// find indices
splitIndices.push_back(-1);
if(nLineSize!=0 && strLine[0]=='/')
{
splitLine.push_back(strLine.substr(0,1));
splitIndices[0]=0;
}
for(int i = 1; i < nLineSize; i++)
{
if(strLine[i] == '/')
splitIndices.push_back(i);
}
// fill split lines
for(int i = 1; i <int(splitIndices.size()); i++)
{
strTempString = strLine.substr(splitIndices[i-1]+1, (splitIndices[i] - (splitIndices[i-1]+1) ));
splitLine.push_back(strTempString);
}
Following change may help:
if (!strLine.empty() && strLine.back() != '/') {
splitIndices.push_back(nLineSize); // end index
}
// fill split lines
for(int i = 0; i < (int)splitIndices.size(); i++)
{
if (splitIndices[i] == 0) {
splitLine.push_back("/");
} else {
strTempString = strLine.substr(nCharIndex, (splitIndices[i] - nCharIndex));
splitLine.push_back(strTempString);
}
nCharIndex = splitIndices[i] + 1;
}
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::string s1 = "/home/desktop/test/";
std::string s2 = "../folder1/folder2/../pic.pdf/";
std::vector<std::string> v1;
std::istringstream is1( s1 );
std::string t;
while ( std::getline( is1, t, '/' ) )
{
if ( t.empty() ) v1.push_back( "/" );
else v1.push_back( t );
}
for ( const std::string &t : v1 ) std::cout << t << std::endl;
std::cout << std::endl;
std::vector<std::string> v2;
std::istringstream is2( s2 );
while ( std::getline( is2, t, '/' ) )
{
if ( t.empty() ) v2.push_back( "/" );
else v2.push_back( t );
}
for ( const std::string &t : v2 ) std::cout << t << std::endl;
}