2013-07-25 1 views
0

У меня есть file.dat и его форматлексемы строки, чтобы получить целые числа из файла

1303100643 115.83 
1303100644 115.94 
1303100645 115.80 
1303100646 115.99 
1303100647 115.74 
1303100648 115.11 

здесь является PHP-код, где я пытаюсь получить нужное число, например, в первой строке я бы хотели бы получить только значение «115»

while (!feof($file_handle)) { 
    set_time_limit(0); 
    $line_of_text = fgets($file_handle, 1024); 
    $reading=strtok($line_of_text[0]," "); 
    echo $reading[0]; 
} 

, если я использую reading[0] результат просто "1"

на reading[1] дает ошибку

SCREAM: Подавление ошибок игнорируется (!)

Примечание: Uninitialized строка смещения: 1 в C: \ WAMP \ WWW \ Delta Compression \ MaxLength.php в строке 16"

ответ

1

Вы не используете strtok() соответствующим strtok() инициализируется, а затем каждый. последующий вызов дает следующий маркер так $reading[0] действительно тянет первый символ строки

Вы используете strtok() как explode(), так что просто использовать explode():..

while (!feof($file_handle)) { 
    set_time_limit(0); 
    $line_of_text = fgets($file_handle, 1024); 
    $reading=explode(" ", $line_of_text[0]); 
    echo $reading[0]; 
} 

я хотел бы получить только значение «115»

Вы могли бы просто привести результат к int или использовать int_val():

echo (int)$reading[1]; 
+0

Вы спасатель: D – Waqas

1

Я думаю, вы должны смотреть в файл() и explode(). Файл() будет считывать каждую строку файла в массив для вас, тогда вы можете использовать explode() для пробела и десятичной точки.

2

Использование регулярных выражений будет быстрее

$data = file_get_contents("file.txt"); 
preg_match_all("/([0-9]{10}) ([0-9]{3}\.[0-9]{2})/",$data,$Matches); 

//Use below if you want an associative array with the first 10 numbers 
//being the keys and the second numbers being the values 
$myData = array_combine($Matches[1],$Matches[2]); 

([0-9]{10}) Матчи первые 10 цифр 0-9,

([0-9]{3}\.[0-9]{2}) сопоставляет следующий набор чисел, который имеет 3 число 0-9, то период, то 2 Чем больше номеров 0-9

$ матчи будут

Array 
(
    [0] => Array 
     (
      [0] => 1303100643 115.83 
      [1] => 1303100644 115.94 
      [2] => 1303100645 115.80 
      [3] => 1303100646 115.99 
      [4] => 1303100647 115.74 
      [5] => 1303100648 115.11 
     ) 

    [1] => Array 
     (
      [0] => 1303100643 
      [1] => 1303100644 
      [2] => 1303100645 
      [3] => 1303100646 
      [4] => 1303100647 
      [5] => 1303100648 
     ) 

    [2] => Array 
     (
      [0] => 115.83 
      [1] => 115.94 
      [2] => 115.80 
      [3] => 115.99 
      [4] => 115.74 
      [5] => 115.11 
     ) 

) 

код против кода:

JasonMcCreary

$time1=microtime(); 
$mydata = array(); 
$file_handle = fopen("data.txt","r"); 

while (!feof($file_handle)) { 
    set_time_limit(0); 
    $line_of_text = fgets($file_handle, 1024); 
    $reading=explode(" ", $line_of_text); 

    $mydata[] = $reading; 
} 
fclose($file_handle); 
$time2 =microtime(); 

Чтение построчно и использование взрываются

1374728889 0.20137600 :: 1374728889 0.20508800 
0.20508800 
0.20137600 
---------- 
0.00371200 

Mine

$time1=microtime(); 

$data = file_get_contents("data.txt"); 
preg_match_all("/([0-9]{10}) ([0-9]{3}\.[0-9]{2})/",$data,$Matches); 
$myData = array_combine($Matches[1],$Matches[2]); 

$time2=microtime(); 

echo $time1." :: ".$time2; 

Использование FGC и регулярные выражения

1374728889 0.20510100 :: 1374728889 0.20709000 
0.20709000 
0.20510100 
---------- 
0.00198900 
+0

Пока он работает, я не уверен, что регулярное выражение является правильным инструментом для работы. –

+0

@JasonMcCreary, Как так? меньше кода, более ясно, что происходит, и он может просто использовать 'array_combine' для создания ассоциативного массива:' $ myData = array_combine ($ Матчи [1], $ Матчи [2]); 'кажется правильным инструментом , –

+0

, если вам удобно с регулярными выражениями, регулярное выражение является ** идеальным ** инструментом для этого задания, предполагая, что вход надежно согласован (как представляется, он). меньше набирать всегда приятно. – sgroves

1

Вы можете использовать explode, как и другие ответы предложили, или вы могли бы получить позиции пространства и десятичной точки и использовать substr, чтобы получить символы между ними. Если предположить, что вход соответствует, либо strpos или strrpos будет работать для этого:

$line = '1303100643 115.83'; 

$space_pos = strrpos($line, ' '); 
$decimal_pos = strrpos($line, '.'); 

$number = substr($line, $space_pos, $space_pos + count($line) - $decimal_pos); 

Другой подход был бы получить все, что после того, как пространство, а затем взять его пол или бросить его в целое число. К счастью, вы можете сделать это в удобном для чтения Однострочник, используя те же функции, как и в предыдущем примере:

$number = (int)substr($line, strrpos($line, ' ')); 

Или вы могли бы использовать регулярное выражение, которое, вероятно, ваш самый простой вариант здесь, если вам 're знакомы с регулярным выражением:

if (preg_match('|(\d+)(\.\d+)?$|', $line, $matches)) { 
    $number = $matches[0]; 
} 

Нарушение этого регулярного выражения вниз ...

  • ( - открытая группа (содержание входить $matches[0])
  • \d+ - соответствовать одной или более цифр
  • ) - закрыть захват группы
  • ( - открыть другую группу (мы собираемся сделать эту группу опционально)
  • \. - соответствует лите. .
  • \d+ - матч один или несколько цифр
  • ) - закрыть захват группы
  • ? - сделать предшествующая группа необязательно (это позволяет ниточки как 1303100650 115, если это необходимо)
  • $ - конец матча строки

Эти примеры предназначены только для одной строки. Очевидно, вы захотите сделать это в цикле (или просто используйте preg_match_all).

Смежные вопросы