Problem creating while Loop listing each occurance of a number in a string | Member | | Join Date: Sep 2007
Posts: 52
| |
Hi,
I created a while-loop which will basically go through each number in a string and list the positions of the desired number.
For example suppose I have a string sa "12123124" and I want to list all the positions of "1" the output should be 0, 2 and 5.
My work out below is: -
<html>
-
<body>
-
<?php
-
$number = "12123124";
-
$posFirst = 0; // Computer counts from 0.
-
$posLast = strlen($number)-1; // Since we are counting from 0, we need to
-
// adjust the last position accordingly
-
-
While($posFirst <= $posLast)
-
{
-
$posFirst = strpos($number, "1", $posFirst);
-
echo $posFirst."<p>";
-
$posFirst = $posFirst+1;
-
-
-
}
-
-
?>
-
</body>
-
-
</html>
-
The output I get is an infinite loop and I don't get what's causing it to loop forever.
0
2
5
2
5
2
5
2
5
2
5
2
Any idea would be appreciated. Thanks.
|  | Moderator | | Join Date: Aug 2008 Location: Leipzig, Germany
Posts: 3,642
| | | re: Problem creating while Loop listing each occurance of a number in a string
It's the last cycle. In the incrementation $posFirst (which is at that moment: false) is set to 1 (false +1 = 1), you could either break out (if (is_boolean($posFirst)) break;) or use preg_match_all() with the PREG_OFFSET_CAPTURE flag instead of the while loop.
regards
| | Member | | Join Date: Sep 2007
Posts: 52
| | | re: Problem creating while Loop listing each occurance of a number in a string Quote:
Originally Posted by Dormilich It's the last cycle. In the incrementation $posFirst (which is at that moment: false) is set to 1 (false +1 = 1) I didn't get it. The increment in line 13 merely increments the value. So $posFirst was initialised to 0 then it became 1 after first run. Why is it false + 1 = 1?
|  | Moderator | | Join Date: Nov 2006 Location: Iceland
Posts: 3,746
| | | re: Problem creating while Loop listing each occurance of a number in a string
Yea. The problem is that if the strpos function doesn't find a match, it returns false. Which PHP will convert into 1 when you try to compare it with another integer.
If I were doing this, I would simply check if the return value of that function was false.
Like: -
$position = -1;
-
while($position = strpos($heystack, $needle, $position + 1))
-
{
-
echo "Found at $position<br />";
-
}
-
|  | Moderator | | Join Date: Aug 2008 Location: Leipzig, Germany
Posts: 3,642
| | | re: Problem creating while Loop listing each occurance of a number in a string Quote:
Originally Posted by Atli If I were doing this, I would simply check if the return value of that function was false. definitely more elegant than my solution.... *sigh*
| | Member | | Join Date: Sep 2007
Posts: 52
| | | re: Problem creating while Loop listing each occurance of a number in a string Quote:
Originally Posted by Atli Yea. The problem is that if the strpos function doesn't find a match, it returns false. Which PHP will convert into 1 when you try to compare it with another integer.
If I were doing this, I would simply check if the return value of that function was false.
Like: -
$position = -1;
-
while($position = strpos($heystack, $needle, $position + 1))
-
{
-
echo "Found at $position<br />";
-
}
-
Ok so, you intially set the value of $position to -1.
In the first run you are searching from position 0 ($position + 1, so -1 +1 = 0) and it found a value and prints it.
I am kind of lost what happens in the second pass through the while loop. Because you are not using condition checking == just =. So how does the computer know when to break off?
I get how you say it returns a false like that php link in your post says Returns the position as an integer. If needle is not found, strpos() will return boolean FALSE. | | Member | | Join Date: Sep 2007
Posts: 52
| | | re: Problem creating while Loop listing each occurance of a number in a string
Actually sorry guys ignore me.
I forgot that a variable in PHP can take different values like $var can be set to take string when you say
$var = "hello";
but later becomes a boolean if you say $var = FALSE or something like that. So after strpos() finishes searching the string it returns a boolean false. So the $position in the while loop of Atli's code becomes a boolean (false more specifically) and hence it breaks out.
I couldn't get how it was set to take string earlier and now taking boolean FALSE all of a sudden. Blame it on too much C coding.
Thanks for your help Atli & Dormilich.
| | Newbie | | Join Date: Sep 2008 Location: Washington DC
Posts: 25
| | | re: Problem creating while Loop listing each occurance of a number in a string
I thought this was an interesting problem, and I played with it some.
First I added an "echo" at the beginning of the loop: -
while($posFirst <= $posLast) {
-
echo $posFirst."-->"; //$posFirst value before the call to strpos()
-
$posFirst = strpos($number, "1", $posFirst);
-
echo $posFirst."<p>\n"; //$posFirst value AFTER the call
-
}
-
and got this output:
0-->0<p>1-->2<p>3-->5<p>6--><p>1-->2<p>3-->5<p>6--><p>1-->2<p>
which displays in browser as:
0-->0
1-->2
3-->5
6-->
1-->2
3-->5
6-->
1-->2
So, calling strpos with 0 returns 0. Adding 1 gives you 1.
2nd time in the loop: calling strpos with 1 returns 2. Adding 1 gives you 3.
3rd time in the loop: calling strpos with 3 returns 5. Adding 1 gives you 6.
4th time in the loop. calling strpos with 6 returns false. Adding 1 gives you 1 !!!
5th time in the loop: calling strpos with 1 returns 2. Adding 1 gives you 3.
and so on...
I was wondering if ++ acts differently, and it does! Replacing the last line in the loop with: $posFirst++;
gives the following output:
0-->0
1-->2
3-->5
6-->
-->0
1-->2
So, using ++ operator on false yields false, but adding 1 to false makes a 1.
|  | Moderator | | Join Date: Nov 2006 Location: Iceland
Posts: 3,746
| | | re: Problem creating while Loop listing each occurance of a number in a string
There is a bug in my previous code! (Hard to believe... I know :P)
But first, let me explain.
In a conditional statement, like a while or a if statement, PHP will look for a TRUE value, which is basically the same as comparing everything inside the while with TRUE.
So: -
// This:
-
while(true)
-
// Is exactly like doing
-
while(true == true)
-
-
// And this
-
while(strpos($h, $n))
-
// Is exactly like
-
while(strpos($h, $n) == true)
-
And, being both very smart and a bit annoying, PHP will consider any number above 0 and any non-empty string to be TRUE, but evaluating NULL, 0 and "" as FALSE.
So, strpost, returning a number when it finds a match and FALSE when it doesn't, will be considered TRUE when it finds a match...
With one exception (which is what I overlooked in my previous code).
When it finds a match at the first index (0), it returns 0, which will be evaluated as FALSE, ending the loop prematurely.
So to fix that, we just look for a boolean value rather than FALSE.
Like: -
$position = -1;
-
while(!is_bool($position = strpos($heystack, $needle, $position + 1)))
-
{
-
echo "Found at $position<br />";
-
}
-
Sorry about that. Was eating when I wrote my first post :P
| | Member | | Join Date: Sep 2007
Posts: 52
| | | re: Problem creating while Loop listing each occurance of a number in a string Quote:
Originally Posted by Atli And, being both very smart and a bit annoying, PHP will consider any number above 0 and any non-empty string to be TRUE, but evaluating NULL, 0 and "" as FALSE. Yeah it did terminate after printing zero but I thought there was something wrong with my syntax in while loop which is causing it to terminate at 0. Thanks for clarifying.
| | Member | | Join Date: Sep 2007
Posts: 52
| | | re: Problem creating while Loop listing each occurance of a number in a string
that code works fine. Had a little trouble getting my head around that is_bool() becuase at first it looked like this:
is_bool(FALSE) is TRUE but digging a little deeper, is_bool looks at the type of variable not the content of the variable.
For a first timer dealing with is_bool() function it can be a little tricky! Kind of like a brain teaser.
|  | Moderator | | Join Date: Aug 2008 Location: Leipzig, Germany
Posts: 3,642
| | | re: Problem creating while Loop listing each occurance of a number in a string Quote:
Originally Posted by Alien What happens when strpos returns a FALSE after finishing searching the string for $needle? Because logically when it $position will then be FALSE and
!is_bool(FALSE) is same as TRUE and hence it'll dig again into the loop. er no, is_bool() checks for a boolean type, so both true and false return true as result, which is negated and therefore it breaks the loop.
regards
|  | Moderator | | Join Date: Nov 2006 Location: Iceland
Posts: 3,746
| | | re: Problem creating while Loop listing each occurance of a number in a string Quote:
Originally Posted by Alien that code works fine. Had a little trouble getting my head around that is_bool() becuase at first it looked like this:
is_bool(FALSE) is TRUE but digging a little deeper, is_bool looks at the type of variable not the content of the variable. Yea I can see why it could be confusing at first :)
It's in a series of "is_*" functions that check for all sorts of variable types.
Can be a little difficult to use cause PHP is so good at converting the types for you.
Like using is_int() to check numbers from user input will not work, because user input is always a string. But using numbers from user input in math works fine because PHP just converts it when it needs to.
It's very smart, but potentially very annoying :)
|  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,366 network members.
|