473,395 Members | 2,437 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Problem creating while Loop listing each occurance of a number in a string

61
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:
Expand|Select|Wrap|Line Numbers
  1. <html>
  2.     <body>
  3.         <?php
  4.             $number = "12123124";
  5.             $posFirst = 0; // Computer counts from 0.
  6.             $posLast = strlen($number)-1; // Since we are counting from 0, we need to 
  7.                                           // adjust the last position accordingly
  8.  
  9.             While($posFirst <= $posLast)
  10.             {
  11.                 $posFirst = strpos($number, "1", $posFirst);
  12.                 echo $posFirst."<p>";
  13.                 $posFirst = $posFirst+1;
  14.  
  15.  
  16.             }
  17.  
  18.         ?>
  19.     </body>
  20.  
  21. </html>
  22.  
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.
Sep 23 '08 #1
12 2067
Dormilich
8,658 Expert Mod 8TB
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
Sep 23 '08 #2
Alien
61
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?
Sep 23 '08 #3
Atli
5,058 Expert 4TB
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:
Expand|Select|Wrap|Line Numbers
  1. $position = -1;
  2. while($position = strpos($heystack, $needle, $position + 1))
  3. {
  4.   echo "Found at $position<br />";
  5. }
  6.  
Sep 23 '08 #4
Dormilich
8,658 Expert Mod 8TB
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*
Sep 23 '08 #5
Alien
61
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:
Expand|Select|Wrap|Line Numbers
  1. $position = -1;
  2. while($position = strpos($heystack, $needle, $position + 1))
  3. {
  4.   echo "Found at $position<br />";
  5. }
  6.  
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.
Sep 23 '08 #6
Alien
61
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.
Sep 23 '08 #7
Marjeta
25
I thought this was an interesting problem, and I played with it some.

First I added an "echo" at the beginning of the loop:
Expand|Select|Wrap|Line Numbers
  1. while($posFirst <= $posLast) {
  2.    echo $posFirst."-->";   //$posFirst value before the call to strpos()
  3.    $posFirst = strpos($number, "1", $posFirst);
  4.    echo $posFirst."<p>\n";   //$posFirst value AFTER the call
  5. }
  6.  
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.
Sep 23 '08 #8
Atli
5,058 Expert 4TB
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:
Expand|Select|Wrap|Line Numbers
  1. // This:
  2. while(true)
  3. // Is exactly like doing
  4. while(true == true)
  5.  
  6. // And this
  7. while(strpos($h, $n))
  8. // Is exactly like
  9. while(strpos($h, $n) == true)
  10.  
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:
Expand|Select|Wrap|Line Numbers
  1. $position = -1;
  2. while(!is_bool($position = strpos($heystack, $needle, $position + 1)))
  3. {
  4.     echo "Found at $position<br />";
  5. }
  6.  
Sorry about that. Was eating when I wrote my first post :P
Sep 23 '08 #9
Alien
61
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.
Sep 23 '08 #10
Alien
61
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.
Sep 23 '08 #11
Dormilich
8,658 Expert Mod 8TB
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
Sep 23 '08 #12
Atli
5,058 Expert 4TB
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 :)
Sep 23 '08 #13

Sign in to post your reply or Sign up for a free account.

Similar topics

6
by: Nimmi Srivastav | last post by:
Brief:- I am having trouble getting a FileWriter to write to a non-existent file if I instantiate the FileWriter with a String that is manipulated at run time. It works fine with a hard-coded char...
2
by: CharitiesOnline | last post by:
Hello, I have set this script up to add paging to a search results page. Which on the first page works fine. I calculates how many pages there should be depending on the number of results returned...
6
by: | last post by:
I am rewriting a C++ application in C#. This file has a combination of Text and Binary data. I used CFile before to read the text. If I hit a certain string that denotes the following data is...
7
by: news.hku.hk | last post by:
how to count the occurance of a character in a string ? e.g. #include <iostream> #include <string> using namespace std; int main (){ string text = "abc, def, ghi, jkl, mno"; // how to count...
1
by: Thanks | last post by:
I have a routine that is called on Page_Init. It retrieves folder records from a database which I display as Link Buttons in a table cell. I set the table cell's bgcolor to a default color (say...
11
by: Siv | last post by:
Hi, I seem to be having a problem with a DataAdapter against an Access database. My app deletes 3 records runs a da.update(dt) where dt is a data.Datatable. I then proceed to update a list to...
2
by: ajikoe | last post by:
Hi, I tried to follow the example in swig homepage. I found error which I don't understand. I use bcc32, I already include directory where my python.h exist in bcc32.cfg. /* File : example.c...
4
by: Zerofury | last post by:
Okay here's what i'm trying to do. I want to create an array and fill it with objects, so that when i create a method to alphabetize them, all of the pieces (the price, name, ect) don't get all out...
3
by: waynejr25 | last post by:
can anyone help me add a function that will count the occurance of each word in an input file. here's the code i have so far it counts the number of characters, words, and lines but i need the...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.