手动将fgetc文件指针移动到下一行

Question 1: How can I manually move the fgetc file pointer from its current location to the next line?

I'm reading in data character by character until a specified number of delimiters are counted. Once the delimiter count reaches a certain number, it needs to copy the remainder of the line until a new line (the record delimiter). Then I need to start copying character by character again starting at the next record.

Question 2: Is manually moving the file pointer to the next line the right idea? I would just explode(at " ") but I have to count the pipe delimiters first because " " isn't always the record delimiter.

Here's my code (it puts all the data into the correct record until it reaches the last delimiter '|' in the record. It then puts the rest of the line into the next record because I haven't figured out how to make it correctly look for the ' ' after specified # of | are counted):

$file=fopen("source_data.txt","r") or exit ("File Open Error");
$record_incrementor = 0;
$pipe_counter = 0;

while (!feof($file))
    {
        $char_buffer = fgetc($file);
        $str_buffer[] = $char_buffer;

            if($char_buffer == '|')
            {
                $pipe_counter++;
            }
            if($pipe_counter == 46) //Maybe Change to 46
            {   
                $database[$record_incrementor] = $str_buffer;
                $record_incrementor++;
                $str_buffer = NULL;
                $pipe_counter = 0;
            }


    }

Sample Data:

1378|2009-12-13 11:51:45.783000000|"Pro" |"B13F28"||""|1||""|""|""|||False|||""|""|""|""||""||||||2010-12-15 11:51:51.330000000|108||||||""||||||False|""|""|False|""|||False
1379|2009-12-13 12:23:23.327000000|"TLUG"|"TUG"||""|1||""|""|""|||False|||""|""|""|""||""||||||1943-04-19 00:00:00|||||||""||||||False|""|""|False|""|||False

I'd say that doing this via file handling functions is a bit clumsy, when it could be done via regular expression quite easily. Just read the entire file into a string using file_get_contents() and doing a regular expression like /^(([^|]*\|){47}([^ ]*))/m with preg_match_all() could find you all the rows (which you can then explode() using | as the delimiter and setting 48 as the limit for number of fields.

Here is a working example function. The function takes the file name, field delimiter and the number of fields per row as the arguments. The function returns 2 dimensional array where first index is the data row number and the second is the field number.

function loadPipeData ($file, $delim = '|', $fieldCount = 48)
{
    $contents = file_get_contents($file);
    $d = preg_quote($delim, '/');
    preg_match_all("/^(([^$d]*$d){" . ($fieldCount - 1) . '}([^
]*))/m', $contents, $match);
    $return = array();

    foreach ($match[0] as $line)
    {
        $return[] = explode($delim, $line, $fieldCount);
    }

    return $return;
}

var_dump(loadPipeData('source_data.txt'));

(Note: this is a solution to the original problem)

You can read to the end of the line like this:

while (!feof($file) && fgetc($file) !== '
');

As for whether or not fgetc is the right way to do this... your format makes it difficult to use anything else. You can't split on , because there may be newlines within a field, and you can't split on |, because the end of the record doesn't have a pipe.

The only other option I can think is to use preg_match_all:

$buffer = file_get_contents('test.txt');
preg_match_all('/((?:[^|]*\|){45}[^
]*
)/', $buffer, $matches);
foreach ($matches[0] as $row) {
  $fields = explode('|', $row);
}

Answer to the modified question:

To read from the file pointer to the end of the line, you can simply use the file reading function fgets(). It returns everything from the current file pointer position until it reaches the end of the line (and also returns the end of the line character(s)). After the function call, the file reading pointer has been moved to the beginning of the next line.