Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect a newline character

Tags:

php

the following is part of myfunction which opens a file and places the pointer at the end. It then tests each character $char in reverse order until it finds a newline or a carriage return character.

The problem is it is not recognising these characters.

The function is as follows:

while(count($results) < $limit && fseek($this->_pointer, $offset, SEEK_END) >= 0) {
    $char = fgetc($this->_pointer);
    if($char == '\n' || $char == '\r'){
        print("YAY");
        $offset --;
        $data = $this->explodeData(fgets($this->_pointer, 1024));
        array_push($results, $this->formatRow($data));
    }
    $offset--;
}

It never manages to print("YAY") however it is successfully testing each character. The file it is reading definitely has newlines in it. (The file was created by another function and has had "\n" inserted in it, this is showing inside it and is showing in my IDE successfully as being on alternate lines).

Does anyone know why it is unable to recognise these newline characters?

like image 682
George Reith Avatar asked Jan 05 '12 16:01

George Reith


People also ask

How do you know if a character is a newline?

Simply comparing to '\n' should solve your problem; depending on what you consider to be a newline character, you might also want to check for '\r' (carriage return).

Is newline character printable?

In this case, only the first line would be printed, since the line ends with a newline character ('\n'), which is not a printable character.


3 Answers

To make your code platform agnostic it is better to have your if condition like this:

if($char == PHP_EOL) {
   print("YAY");
   // your rest of the code
}

Thanks to @Félix Gagnon-Grenier comment below.

PHP_EOL might not work on strings that come from other systems. PHP_EOL represents the endline character for the current system.

To make it detect all kind of newline characters including unicode newlines use \R:

preg_match('/\R/', $str);

\R is equivalent of (?>\r\n|\n|\r|\f|\x0b|\x85|\x{2028}|\x{2029})

Code Demo

like image 86
anubhava Avatar answered Oct 27 '22 10:10

anubhava


You are using '\n' instead of "\n".

while(count($results) < $limit && fseek($this->_pointer, $offset, SEEK_END) >= 0) {
    $char = fgetc($this->_pointer);
    if($char == "\n" || $char == "\r"){
        print("YAY");
        $offset --;
        $data = $this->explodeData(fgets($this->_pointer, 1024));
        array_push($results, $this->formatRow($data));
    }
    $offset--;
}

"\n" == LF character
'\n' == '\n';

// Variables are effected also
$var = 'foo';

print "$var"; // prints 'foo';
print '$var'; // prints '$var';
like image 35
Xeoncross Avatar answered Oct 27 '22 10:10

Xeoncross


use double quotes instead of single quotes around the "\n" and "\r"

i had a similiar nightmare a while back, until i realized that php does not use escape characters unless they're in double quotes.

like image 37
Jimmery Avatar answered Oct 27 '22 11:10

Jimmery