Jump to content

reading from flat file


Dragen

Recommended Posts

Hi,

I'm trying to write a script to calculate my hours for work.

I have a text file with my hours written down as a timestamp..

11:40 01/04/2007
13:30 01/04/2007

19:30 01/04/2007
19:40 01/04/2007

21:10 01/04/2007
00:15 01/04/2007

Basically the first line is my start time the one below is when I finish. Each work block is broken up by an empty line.

I've never tried a file based system before as I've always used databases, but I'm wanting to use a flat file system for this.

How can I take the information from the file?

 

I want it to read as something like:

$start = first line
$end = second line

 

Then I'd have a for each statement I guess.. so

foreach (block of work)
{
  echo "start: " . $start;
  echo "end: " . $end;
}

I'm not sure how to work with flat files so how would I go about reading from it and then defining what parts of the file is what?

Thanks

Link to comment
Share on other sites

well.. what i would have done first is seperating time and date with something else than a blank space.. maybe using ||

 

then i would use file()

 

$file = file(filename);

 

then i would do something like this this reads every line in the $file array

$work = array();
$i = 0;

foreach($file as $result) {
$i++;
$work[] = $result;
}

 

now you need to separate time from date.

$count = 0;
foreach($count <= $i) {
$workInfo = explode("||", $work)
$workTime = $workInfo[0];
$workDate = $workInfo[1];
$count++;
}

 

but i think it will be a conflict with the blank line.. and i'm not sure on how to bypass it ... but most likely with an if statement inside the last foreach that sais something about "if there's no || in $workInfo, skip it" or something like that.. think this should work

Link to comment
Share on other sites

okay, what I've got is this

<?php
$file = file('hours.txt');
$work = array();
$i = 0;

foreach($file as $result) {
$i++;
$work[] = $result;
}

$count = 0;
foreach($count <= $i) {
$workInfo = explode("||", $work);
$workTime = $workInfo[0];
$workDate = $workInfo[1];
$count++;
}
?>

Although I'm recieving this error:

Parse error: parse error, unexpected ')' in /home/fhlinux181/g/gimppro.co.uk/user/htdocs/test/hours.php on line 21

can't find the problem though..

also, using '$file = file('hours.txt');', do I still need to include something like this:

$fp = fopen('hours.txt','r');
if (!$fp) {
echo 'ERROR: Unable to open file.'; exit;
}

Link to comment
Share on other sites

line 21 is

foreach($count <= $i) {

 

and wildbug I tried your suggesstion and it outputted the data like this

Start: 11:40 01/04/200
End: 13:30 01/04/2007 19:30 01/04/2007 19:40 01/04/2007 20:00 01/04/2007 20:03 01/04/2007 21:10 01/04/2007 00:15 01/04/2007

It seems to have a problem once it reaches the blank line..

Is there a better way of putting the data into the flat file, so that I can display it easily?

As I've said I've never used flat files before, so I just wrote my txt file how I thought easy to read...

Link to comment
Share on other sites

hmm... weird... i'm using the exact same code for my calendar script... to grab entries for selected date...

 

this is my exact code (copy/paste):

<?php
			$file = file("$scheFILE");
			$i = 0;
			$sche = array();
			foreach ($file as $result) {
				$i++;
				$sche[] = $result;
			}
			$cnt = 0;
			while ($cnt < $i) {
				$schInfo = explode("||", $sche[$cnt]);
				$schTime = $schInfo[0];
				$schTitle = $schInfo[1];
				$schMessage = $schInfo[2];
				echo $schTime." :: ".$schTitle."<br>";
				echo $schMessage."<hr size=1 color=#000000>";
				$cnt++;
			}
?>

Link to comment
Share on other sites

Ah, damn.  I didn't test it.  It's possible that it's a DOS file and has \r\n instead of \n or that there's more whitespace on that blank line.  Perhaps you could use preg_split('/\s{2,}/',$contents) instead of explode (or {4,} if \r\n, maybe).

 

If you've been careful about entering your data, i.e., consistent, then it should be no trouble to parse it automatically, whatever method you end up using.

Link to comment
Share on other sites

My file is just a .txt file. There is no whitespace on the blank lines except the actual existence of the blank line itself.. no spaces etc.

 

I've now got the code as:

<?php
$contents = file_get_contents('hours.txt');
$contents = preg_split('/\s{2,}/',$contents);
foreach ($contents as $value) {
echo "<p align=\"left\">Start: " . substr($value,0,16);
echo "<br />End: " . substr($value,17) . "</p>";
}
?>

which works to an extent.

For some reason it outputs everythings as start, and I get nothing for end.

Start: 11:40 01/04/2007
End:

Start: 13:30 01/04/2007
End:

Start: 19:30 01/04/2007 // this should be under the end above
End:

Start: 19:40 01/04/2007
End:

Start: 20:00 01/04/2007
End:

Start: 20:03 01/04/2007
End:

Start: 21:10 01/04/2007
End:

Start: 00:15 01/04/2007
End: 

Link to comment
Share on other sites

Here is some basic code that should help you on your way:

<?php
$ts = file('timesheet.txt');
for ($i=0;$i<count($ts);$i += 3) {
$tmp = array();
$tmp[] = 'Start: ' . trim($ts[$i]);
$tmp[] = 'End: ' . trim($ts[$i+1]);
echo implode('<br>', $tmp) . '<br><br>';
}
?>

 

Ken

Link to comment
Share on other sites

this should work

 

<?php
$contents = file_get_contents('hours.txt');
$contents = preg_split('/\s{2,}/',$contents);
$value = array();
foreach ($contents as $value) {
echo "<p align=\"left\">Start: " . substr($value[0],0,16);
echo "<br />End: " . substr($value[1],17) . "</p>";
}
?>

Link to comment
Share on other sites

I'm glad that worked; I was almost out of ideas  :-)

 

Your file is probably a DOS (Windows) format which uses two characters to indicate a carriage return (\r\n) whereas UNIX uses just the one (\n - newline), so the whitespace pattern indicator (\s) will match at each of these -- \r and \n.  To break at the blank lines I was assuming a double space -- \n\n, but it was really \r\n\r\n.  Thus, \s{4,} is needed instead of \s{2,}.

Link to comment
Share on other sites

That's one of reasons to use the trim() function. It will remove the newline character from the end of a line whether the new line character consists of "\n", "\r\n", or "\r". If you use the trim() function, your code is portable across different OS's.

 

Ken

Link to comment
Share on other sites

You could use substr() since you have a nice, even, zero-padded format.  I like regular expressions, though, so I might jump right to that.  In fact, you could replace the previous code we've discussed with a preg_match_all() like so:

 

$contents = file_get_contents('hours.txt');
preg_match_all('|(\d\d:\d\d) (\d\d/\d\d/\d{4})\s+(\d\d:\d\d) (\d\d/\d\d/\d{4})|',$contents,$matches,PREG_SET_ORDER);
foreach ($matches as $value) {
printf("Start time: %s\nStart date: %s\n End time: %s\n End date: %s\n\n",
	$value[1],$value[2],$value[3],$value[4]);
}

Link to comment
Share on other sites

thanks. That works.. could you please explain to me what this actually means?

preg_match_all('|(\d\d:\d\d) (\d\d/\d\d/\d{4})\s+(\d\d:\d\d) (\d\d/\d\d/\d{4})|',$contents,$matches,PREG_SET_ORDER);

I can't quite figure it out and if I'm told what it means then I can learn from it easier.

thanks

Link to comment
Share on other sites

actually, I think I've got it now...

preg_match_all('|(\d\d:\d\d) (\d\d/\d\d/\d{4})\s+(\d\d:\d\d) (\d\d/\d\d/\d{4})|',$contents,$matches,PREG_SET_ORDER);

The \d means number.

{4} is the blank line.

not sure what the \s+ does though

Link to comment
Share on other sites

\d is a numerical digit, same as the character class [0-9]

{4} is a quantifier.  \d{4} means "four digits" (the year).  It's equivalent to \d\d\d\d, but takes less space.

\s+ means "one or more whitespace characters."  \s is a whitespace character -- tab, space, return, both \r and \n.  The plus sign is also a quantifier, meaning "one or more."  This matches the line break between the start and end timestamps.

The parentheses, in this case, capture the subpatterns for inclusion in the $matches array.

 

More on quantifiers (not all relevant to the preceeding pattern):

 

* means "zero or more," same as {0,}.

? means "zero or one," same as {0,1} (Edit: forgot this one.)

+ means "one or more," same as {1,}.

{5,10} means "from five to ten occurences."

{,50} means "a maximum of 50 occurences (including zero)."

{50,} means "at least 50 occurences."

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.