Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strpos() within while loop never ends

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?

like image 506
Yang Avatar asked Dec 27 '22 09:12

Yang


2 Answers

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);
}
like image 190
Ja͢ck Avatar answered Jan 09 '23 02:01

Ja͢ck


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

like image 36
Passerby Avatar answered Jan 09 '23 01:01

Passerby