strpos() within while loop never ends
Asked Answered
M

4

5

There's a string,

$string = 'Foo, Bar, Test,';

All I want to do is to count the number of the commas within a string.

But everything leads to infinite while loop.

So, I've tried #1:

$count = 0;

while($pos = strpos($string, ',') !== FALSE){
    $count++;
    // Never ends
}

And also #2,

while(true){
  if ( strpos($string, ',') !== FALSE ){
     $count++;
  } else {
    break;
  }
}

They both never end. Where's the problem?

Mas answered 18/2, 2013 at 6:56 Comment(2)
strpos() doesn't alter $string. You'll get the same result each iteration.Shockproof
I know it doesn't answer your question but this might be one of those "asking the wrong question" situations. Both Prasanth and Jack have offered you the "best" way to count these commas and you really should use their suggested methods for such things.Fante
O
6

You could just use substr_count():

substr_count($string, ',');

In your code, strpos() requires a third parameter to start searching from a particular offset, e.g.:

strpos($string, ',', 12); // start searching from index 12

It doesn't work like an iterator. Something like this would work:

$start = 0;
while (($pos = strpos($string, ',', $start)) !== FALSE) {
  $count++;
  $start = $pos + 1;
}

Update

If you want to get real fancy:

class IndexOfIterator implements Iterator
{
  private $haystack;
  private $needle;

  private $start;
  private $pos;
  private $len;
  private $key;

  public function __construct($haystack, $needle, $start = 0)
  {
    $this->haystack = $haystack;
    $this->needle = $needle;
    $this->start = $start;
  }

  public function rewind()
  {
    $this->search($this->start);
    $this->key = 0;
  }

  public function valid()
  {
    return $this->pos !== false;
  }

  public function next()
  {
    $this->search($this->pos + 1);
    ++$this->key;
  }

  public function current()
  {
    return $this->pos;
  }

  public function key()
  {
    return $this->key;
  }

  private function search($pos)
  {
    $this->pos = strpos($this->haystack, $this->needle, $pos);
  }
}

foreach (new IndexOfIterator($string, ',') as $match) {
  var_dump($match);
}
Ordinate answered 18/2, 2013 at 6:58 Comment(0)
W
3

strpos() returns the first occurrence of the $needle, so unless you specify different $offset, you'll always get the same result, thus the endless loop.

If you insist on using strpos(), try this:

$pos=0;
while(($pos = strpos($string, ',',$pos)) !== FALSE){
    $count++;
    $pos++;
    // This ends
}

Off course you can use substr_count() to make things easier.

Edit:

Live demo

Weathertight answered 18/2, 2013 at 6:59 Comment(0)
M
2

Try this :

$text = 'Foo, Bar, Test,';
echo substr_count($text, ',');

ref: http://php.net/manual/en/function.substr-count.php

Mannos answered 18/2, 2013 at 6:58 Comment(0)
M
0

Or try this if substr_count not fit:

$pos = -1;
$count=0;
while( $pos = strpos($in, ',', $pos+1) !== FALSE){
     $count++;
     }

I didn't test whether you absolutely need !==FALSE. If you use mb_strpos you don't.

Moulden answered 14/11, 2013 at 13:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.