ConfusedOfLife
11-15-2002, 02:08 PM
I'm reading from a file by fgets and I wana find all the "hello"s and show them in a custom color like red! I know that fgets read a line till it reaches the end of line, EOF or the length that we specified for that. And I also know that if for example I give it a length of 50KB, and my line be 90 KB and "hello" starts at 47 KB, then fgets splits the line into 2 parts and since "hel" would be in one line and "lo" in another line, it doesn't highlight it.
One work around is to determine our fgets length ( buffSize ) by this :
buffSize -= buffSize - ( strlen(queryWord) - 1); # queryWord is the word that we're looking for, 'hello' in this case
Another way is to check if the length of the line we got ( $line ) be equal to buffSize-1 and also the last character of this line doesn't be equal to "\n", then we could say that fgets has splitted the line by itself and we can paste the current line and the previous line to each other. ( by means of implode of whatever ). The problem is that it doesn't recognize this second condition :
if ( $line[ strlen($line) -1] == "\n" )
do something
beetle
11-15-2002, 08:22 PM
Is your server Windows or *nix?
Windows will need a \r\n methinks.
ConfusedOfLife
11-16-2002, 08:38 PM
I'm using the firepages webserver, it's something wrong with my array and it does recognize "\n", even though I'm using windows, I also tried "\r\n" and it didn't answer ( coz my code was wrong! ).
This one works, no matter of what buffSize you give it, it'll give you an array containing each line as its elements and then you can search it for your queryWord!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<?PHP
class findWord
{
var $fileName;
var $queryWord;
var $color; # The color of queryWord in output.
var $fp; # file pointer.
var $lines = array();
var $Output;
var $buffSize; # The size of buffer.
function findWord( $fileName, $queryWord, $color = "red", $buffSize = 1024)
{
if ( file_exists($fileName) )
{
$this->fileName = $fileName;
$this->fp = fopen($this->fileName, "r");
$this->queryWord = $queryWord;
$this->color = $color;
$this->buffSize = $buffSize;
$this->lines = $this->readLines( $this->fp, $this->buffSize);
$this->Output = $this->queryLines( $this->lines, $this->queryWord, $this->color);
$this->showFile( $this->Output);
}
else
{
die("Program dies : Invalid file name.");
}
}
function readLines( $fp, $buffSize)
{
# This little line saves the program when a word is at the
# junction between two chunks, i.e. if a word doesn't fit
# in one line and fgets reaches its length sooner than the
# CR and it breaks the line in the middle of our queryWord.
#$buffSize += $buffSize - ( strlen($this->queryWord) - 1 );
$lines = array();
$count = 0;
while ( !feof( $fp) )
{
$lines[$count] = fgets( $fp, $buffSize);
if ( $count != 0 )
{
$temp = $lines[$count-1];
if ( strlen($temp) >= $buffSize-1 &&
$temp[strlen($temp)-1] != "\n"
)
{
$lines[$count-1] .= $lines[$count];
# coz when we increment $count below, it actually doesn't get incremented!
--$count;
}
}
$count++;
}
return $lines;
}
function queryLines( $lines, $queryWord, $color)
{
foreach ( $lines as $key => $val)
{
$holder = explode( $queryWord, $val);
$lines[$key] = implode( "<font color=$color>$queryWord</font>", $holder);
}
return $lines;
}
function showFile( $outPut)
{
foreach ( $outPut as $val)
print "$val <br>";
}
}
# An example instantiation of this class, note that the buffSize
# isn't important anymore, since by pasting all the returned
# strings of fgets together till we find each line exactly ( not
# the chunks that fgets make if the buffSize be less than a line
# length ), we can populate our array by lines and then search
# each slut! for the queryWord.
$ourFile = new findWord("search.txt", "hello", "blue", 5);
?>
</HEAD>
<BODY>
</BODY>
</HTML>
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.