loop through text file for first number on each line - php

the code below works for the first word on each line, but how do I get the first number on each line? please keep in mind that the number can be 1 digit or it can be 20 digits long
<?php
$file = new SplFileObject("/tmp/test.txt", "r");
$data = array();
while(! $file->eof()) {
$data[] = array_shift(($file->fgetcsv("|")));
}
echo implode(",", $data);
?>

This gets the first number in a string:
function getFirstNumber($str){
$strlen = strlen( $str );
$num = "";
for( $i = 0; $i <= $strlen; $i++ ) {
$char = substr($str, $i, 1);
if(!is_numeric( $char)){
if(!empty($num))
return intval($num);
}else $num .= $char;
}
return intval($num);
}
$str = "asdfas1234241234lkj 1l2k3j4 1k2j3412341234";
echo getFirstNumber($str);
Here's a fiddle.

The code you presented, gets the first part, not the first word.
You have to walk through the array using foreach, array_walk, ...
For example:
<?php
$file = new SplFileObject("/tmp/test.txt", "r");
$data = array();
while(! $file->eof()) {
foreach($file->fgetcsv("|") as $part) {
if (is_numeric($part)) { //or any other numeric check you like
$data[] = $part;
break;
}
}
}
echo implode(",", $data);
?>

Related

foreach doesn't stop the loop on break

I'm trying to post 3 arrays using foreach and for some reason the break at the end isn't working and it outputs the whole list (40+) on to the page.
$file = fopen('names.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
$i = 0;
foreach ($line as $number) {
{
if($i==3){ break; } else {
$rtime = mt_rand(1, 7);
echo $number; }
$i++;
}
}
}
fclose($file);
This is kind of how it looks: take.ms/cLgIh, instead it should only show 3 of these usernames.
<?php
$i = 0;
//I have opened my contact.csv :P
$file = fopen('contact.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
foreach ($line as $number) {
{
if($i==3){ exit(); } else {
$rtime = mt_rand(1, 7);
echo "<br/> i = ".$i.$number.", "; }
}
$i++;
}
}
fclose($file);
?>
I have downloade first sample CSV from here:-http://www.sample-videos.com/download-sample-csv.php
And this code works for me:-
<?php
$file = fopen('SampleCSVFile_2kb.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
$i = 0;
foreach ($line as $number) {
if($i==3){
exit;
} else {
$rtime = mt_rand(1, 7);
echo $number.'<br/>';
echo $i.'<br/>'; // you can remove this line
}
$i++;
}
}
fclose($file);
?>
Output on each page refresh:-
http://prntscr.com/cln2ju
http://prntscr.com/cln2nf
Note:- if still not work then check your CSV file. May be it is corrupted.
Conclusion:- And after all discussion it comes to an end that your CSV file is corrupted. But yes code improvement is needed too
You need to increment $i otherwise it's value will always be 0
$i = 0;
foreach ($line as $number) {
$rtime = mt_rand(1, 7);
echo "$number";
if($i==3) break;
$i++;
}
Also you need to check if your while statement is closing
$file = fopen('names.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
$i = 0;
foreach ($line as $number) {
$rtime = mt_rand(1, 7);
echo $number;
if($i==3) break;
$i++;
}
} //check for this
As I can see in your code example it is missing the closing brace
Also, remove the double quotes from your $number, it's not necessary.
echo $number
You have a mistake is that the break are in the if($i==3) and you declared $i =0, but never increment this. So $i never arrive at 3.

php how to get whole line after spicific character from text file?

I have text file
name,name1
willhaveishere1
name,name2
willhaveishere2
name,name3
willhaveishere3
i want read it and return like that
$nn = name1
$ss = willhaveishere1
with my code i get only name1
my code is
$file1 = "file.txt";
$file = file($file1);
$count = count($file);
if($count > 0) {
$i = 1;
foreach($file as $row) {
$n = strstr($row, 'name,');
$cc = array("name,");
$dd = array("");
$nn = str_replace($cc, $dd, $n);
echo $nn;
$i++; } }
This is probably what you need
if($count > 0) {
foreach($file as $row) {
$pos = strpos($row, ',');
if($pos !== false){
echo substr($row, $pos + 1);
$nn[] = substr($row, $pos + 1);
} else {
echo $row;
$ss[] = $row;
}
}
}
EDIT
Yes, just loop through, but make sure both $nn and $ss has same count, which is depending on your file.
Also Note: mysql_* functions has been deprecated, so please use mysqli or PDO instead
$count = count($nn);
for($i=0; $i < $count; $i++){
$sql = "INSERT INTO users(name, line) VALUES('$nn[$i]', '$ss[$i]')"; mysql_query($sql);
}
EDIT 2
try this example:
$file = array(
0 => 'name,name1',
1 => 'willhaveishere1',
2 => 'name,name2',
3 => 'willhaveishere2',
4 => 'name,name3',
5 => 'willhaveishere3'
);
$count = count($file);
if($count > 0) {
foreach($file as $row) {
$pos = strpos($row, ',');
if($pos !== false){
$nn[] = substr($row, $pos + 1);
} else {
$ss[] = $row;
}
}
}
echo '<pre>';
$count = count($nn);
for($i=0; $i < $count; $i++){
$sql = "INSERT INTO users(name, line) VALUES('$nn[$i]', '$ss[$i]');";
echo $sql.PHP_EOL;
}
You can try this straightforward method:
if($fh = fopen("file.txt","r")){
$nameBefore = false;
//loop through every line of your file
while (!feof($fh)){
$line = fgets($fh);
//check if the name was detected in previous line
if ($nameBefore !== false)
{
//you have the set of name and line, do what you want
echo $nameBefore . ': ' . $line . '<br />';
$nameBefore = false;
}
else
{
//see if the line is made of two coma separated segments and the first one is 'name'
//Remember the name for the next line
$parts = explode(',', $line);
if (count($parts) == 2 && $parts[0] == 'name')
$nameBefore = $parts[1];
}
}
fclose($fh);
}
One option is to use strpos to find the first occurrence of the character in the line, and if found remove everything from the line before that position. This way you are left with only the part of the line you are interested in.
Code:
$character = ',';
$fileHandle = fopen('file.txt', 'r');
while (!feof($fileHandle)) {
// Retrieve the line from the file
$line = fgets($fileHandle);
// If the line contains the character
// Remove everything before the character
$charPos = strpos($line, $character);
if ($charPos !== false) {
$line = substr($line, $charPos + 1);
}
// Do something with the remainder of the line
echo $line . PHP_EOL;
}
fclose($fileHandle);
Output:
name1
willhaveishere1
name2
willhaveishere2
name3
willhaveishere3
If you wish to retrieve the following line, simply do another retrieve line call in your loop:
while (!feof($fileHandle)) {
// Retrieve two lines in one loop iteration
$lineOne = fgets($fileHandle);
$lineTwo = fgets($fileHandle);
}
Making sure to only apply the comma replace part on the first line. This can lead to problems though if your data is... inconsistent.
Hope this helps.

Saving hex data in binary using PHP does not work properly

I am learning PHP and files and I am trying to write some code that put data in a binary file.
here's my code:
Write
<?php
echo "\n\nWRITE: \n\n";
$c = array();
$data = '';
$c['name'] = 'abcdefghijklmnopqrstuvwxyz';
$data .= implode('', $c);
$fp = fopen('test.bin', 'wb');
$len = strlen($data);
echo "\nFILE CONTENT: $data (strlen: $len)\n\n";
for ($i = 0; $i < $len; ++$i) {
$hx = dechex(ord($data{$i}));
fwrite($fp, pack("C", $hx));
}
echo "Last char is: $hx which mean: ";
echo chr(hexdec('7a'));
echo "\n--------------------------------------------\n";
fclose($fp);
Output
FILE CONTENT: abcdefghijklmnopqrstuvwxyz (strlen: 26)
Last char is: 7a which mean: z
Read
<?php
echo "\n--------------------------------------------\n";
echo "\n\nREAD: \n\n";
$fp = fopen('test.bin', 'rb');
$fseek = fseek($fp, 0, SEEK_SET);
if($fseek == -1) {
return FALSE;
}
$data = fread($fp, 26);
$arr = unpack("C*", $data);
$return = '';
foreach($arr as $val) {
$return .= chr(hexdec($val));
}
$n = '';
$arr = array();
$arr['name'] = substr($return, 0, 26);
print_r($arr);
echo "\n--------------------------------------------\n";
Output
Array
(
[name] => abcdefghipqrstuvwxy
)
Where are the missing letters like the z, m, n or o ?
EDIT 6-3-14 7h36 am: I would like to have the .bin file not plain text if possible
You are trying to set HEX chars in a char (C - unsigned char) instruction.
echo "\t";
foreach( array('0x41', 65, 'a') as $o )
echo $o."\t";
echo "\n";
foreach( array('c*','C*','a*','A*','h*','H*','v*','n*','S*') as $o ){
echo $o . "\t";
foreach( array(0x41, 65, "a") as $oo ) {
echo pack($o, $oo);
echo "\t";
}
echo "\n";
}
If you run this, you will see quickly how pack works with the 3 different values of a (HEX, DEC and normal).
You have to use the h instruction to accomplish what you need.
function writeToFile($data) {
$fp = fopen(FILENAME, 'wb');
$len = strlen($data);
for ($i = 0; $i < $len; ++$i) {
$hx = dechex(ord($data[$i]));
$result = fwrite($fp, pack("h*", $hx));
if(!$result) {
// show something
}
}
fclose($fp);
}
Now, for read that data. You will need to use the same one h and split the string you get back (split it using str_split with the parameter 2 since it's HEX 00 = 0 and FF = 255 - assuming you won't go over 255). Since h returns an array with a single element. Once you get your string back, you need to convert the number you get from the ord in the writeToFile using the chr function.
function readFromFile($lenght, $pos = 0) {
$return = '';
$fp = fopen(FILENAME, 'rb');
if(!$fp) {
// show something
}
$fseek = fseek($fp, $pos, SEEK_SET);
if($fseek == -1) {
// show something
}
$data = fread($fp, $lenght);
$data = unpack("h*", $data);
$arr = str_split(current($data), 2);
foreach($arr as $val) {
$return .= chr(hexdec($val));
}
return $return;
}
Now, you create your string and write to the file:
$data = 'This should work properly, thanks for StackOverFlow!';
$len = strlen($data);
writeToFile($data);
Then read back:
echo readFromFile($len);
The content of your file will look like this:
E<86><96>7^B7<86>öWÆF^Bwö'¶^B^G'ö^GV'Æ<97>Â^BG<86>^Væ¶7^Bfö'^B5G^V6¶ôgV'dÆöw^R

echoing foreach loop

i have the following code
$contents = file_get_contents('folder/itemtitle.txt');
$fnamedata = file_get_contents('folder/fname.txt');
$fnamearray = explode("\n", $fnamedata);
$contents = explode("\n", $contents);
foreach ($contents as $key => $itemline)
{
}
foreach ($fnamearray as $key2 => $fname)
{
echo ($fname);
echo ($itemline);
}
what i want to do is to have the first line of each file echo so the output looks like
fname[0},itemline[0],fname[1],itemline[1]
what i am getting with the following is just this
fname[0],fname[1],fname[2].... ect
h
Assuming the indexes will always match:
$contents = file_get_contents('folder/itemtitle.txt');
$fnamedata = file_get_contents('/home/b1396hos/public_html/ofwgkta.co.uk/dd_folder/fname.txt');
$fnamearray = explode("\n", $fnamedata);
$contents = explode("\n", $contents);
for($i = 0; $i < count($contents); $i++)
{
echo $fnamearray[$i];
echo $contents[$i];
}
Since both arrays are simple, consecutive numeric indexed arrays, you can just use a for loop:
$l = max(count($fnamedata),count($contents));
for($i=0; $i<$l; $i++) {
$itemline = $contents[$i];
$fname = $fnamearray[$i];
// do stuff
}

PHP Parsing a .dat file

I have a .dat file that is essentially ; delimited file and I'm trying to convert it to a tab delimited .txt. The problem that I am not sure about is that each row of the new file will be a combination of 3 of the original file's rows, each original row has a different quantity of data. The first column just identifies each row in a grouping. What would be the best way to do this?
Sample original data:
01;zxc;asd;qwe;uio;jkl;asd;123;456
02;lkj;oiu;oji
03;fjifao;vbofekjf;fjieofk;aoijf;voien3984
01;lkj;oiu;fji;eoj;vnk;fji;098;321
02;fji;oje;jvi
03;jie;voi;djv;eojf;38723
End output:
zxc asd qwe uio jkl asd 123 456 lkj oiu oji fjifao vbofekjf fjieofk aoijf voien3984
lkj oiu fji eoj vnk fji 098 321 fji oje jvi jie voi djv eojf 38723
Any ideas?
Here's how I'd do it:
$lines = file($data);
$rows = array();
$row_pivot = -1;
foreach ($lines as $line) {
// Split line by ;
$data = explode(';', trim($line));
// Get the first element
$r_id = array_shift($data);
if ($r_id == '01') {
// When 01 is the first element, start a new row
// You can dump the previous row here as well if you aim for speed
$row_pivot++;
$rows[$row_pivot] = array();
}
// Add data to row
$rows[$row_pivot] = array_merge($rows[$row_pivot], $data);
}
// Print rows
foreach ($rows as $r) {
echo implode("\t", $r)."\n";
}
I would personally explode the data then foreach row in the resulting array, then again explode each line at your delimiter ';' and then format an output that is tab delimited.
<?php
$data = 'LOADED FILE DATA';
$lines = preg_split( '/\r\n|\r|\n/', $data);
$out = '';
foreach($lines as $line){
$parts = explode(';',$line);
foreach($parts as $part){
$out .= $part.'\t';
}
$out .= '\n';
}
echo $out;
?>
code untested.
Should be something like this
$lines = file($filename);
$lineCount = count($lines);
$output = '';
for ($i = 0; $i < $lineCount - 2; $i += 3) {
$newLines = array();
for ($j = $i; $j < $i + 3; $j++) {
list($_, $rest) = explode(';', isset($lines[$j]) ? $lines[$j] : '');
$newLines = array_merge($newLines, $rest);
}
$output .= implode("\t", $newLines) . "\n";
}

Categories