Gábor Erdős Gábor Erdős - 1 month ago 9
C++ Question

Strange behaviour in declaration inside a while condition C++

I am implementing a python like

split()
function in C++ to train myself. I got the idea from this SO thread: Parse (split) a string in C++ using string delimiter (standard C++)

In this code:

while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
std::cout << token << std::endl;
s.erase(0, pos + delimiter.length());
}


The value os
pos
is assigned inside the condition of the
while
loop.

I tried the same thing:

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

std::vector<std::string> split(std::string inp, std::string delimeter){
std::vector<std::string> res;
while (size_t pos = inp.find(delimeter) <= inp.length()){
std::cout << inp << " " << pos << std::endl ;
if (inp.substr(0, delimeter.length()) == delimeter) {
inp.erase(0, delimeter.length());
continue;
}
res.push_back(inp.substr(0, pos));
inp.erase(0, pos);
}
return res;
}

int main() {
for (auto i : split(",,ab,c,,d", ",")){
std::cout << i << " ";
}
std::cout << std::endl;
}


My output is:

,,ab,c,,d 1
,ab,c,,d 1
ab,c,,d 1
b,c,,d 1
,c,,d 1
c,,d 1
,,d 1
,d 1
a b c


My question is why poes it say that the position of
,
in string
,,ab,c,,d 1
is
1
?

And why is the position in
ab,c,,d
is 1 as well?

I modified the code like this:

#include <iostream>
...
size_t pos = 0;
while (pos <= inp.length()){
pos = inp.find(delimeter);
...
}

int main() {
for (auto i : split(",,ab,c,,d", ",")){
std::cout << i << " ";
}
std::cout << std::endl;
}


Where
...
remains unchanged and now it works like a charm, the output is:

,,ab,c,,d 0
,ab,c,,d 0
ab,c,,d 2
,c,,d 0
c,,d 1
,,d 0
,d 0
d 18446744073709551615
ab c d


Just as I expected.

So my question is: Why cant i declare a variable inside a while condition? Isnt the condition is evaluated at all cycle (thus the declaration happen again?) Even at the very first cycle i get the result
1
which is wrong. Why is that?

AnT AnT
Answer
while (size_t pos = inp.find(delimeter) <= inp.length()){

is interpreted as

while (size_t pos = (inp.find(delimeter) <= inp.length())){

while you need a completely different grouping

while ((size_t pos = inp.find(delimeter)) <= inp.length()){

The latter is illegal in C++ though.

It is not possible to declare a variable in while condition and at the same time make it participate in a more complicated conditional expression (like a comparison with another value). When you declare a variable in C++ condition all you can have is its initial value converted to bool.

The modified code, where pos is declared before the loop, properly implements your intent.