douyong4842 2017-02-13 16:15
浏览 136
已采纳

将float的正确值写入csv文件

In the csv file, I have lines with this structure :

Name;timestamp;floatValue
Name;timestamp;floatValue
Name;timestamp;floatValue
...

In my code, I check each value in the line, I filter them,then I want to correct the float value by calling the function floatval, because I have wrong values sometimes like : .904 or 2,454 and using this function returns the right formatted one.

    <?php

    if (($handle = fopen('file.csv', "r+")) !== false) {
        while (($line = fgetcsv($handle, 1024, ";")) !== false) {

          $headers = [
              'name',
              'timestamp',
              'floatValue',
          ];
          $line = array_combine($headers, $line);
          $args = array('name' => array('filter' => FILTER_VALIDATE_REGEXP,
                                                      'options' => array('regexp' => '/^[a-zA-Z0-9_:.()\/]*$/'), ),
                        'timestamp' => array('filter' => FILTER_CALLBACK,
                                                            'options' => 'validateDate', ),
                         'floatValue' => array('filter' => FILTER_VALIDATE_FLOAT),);
    $result = filter_var_array($line, $args);
    $line = correctFloat($line);
    print_r($line);
    }

    }

    fclose($handle);

    function validateDate($date)
    {
      if (!preg_match("/^\d{8}$/", substr($date, 0, 8))) {
          return false;
      }
      if (!checkdate(substr($date, 4, 2), substr($date, 6, 2), substr($date, 0, 4))) {
          return false;
      }
      if (substr($date, 8, 2) > 23 || substr($date, 10, 2) > 59 || substr($date, 12, 2) > 59) {
          return false;
      }

      return true;
    }


function correctFloat($line){
  $float = $line['floatValue'];
  $value = str_replace(",",".",$float);
  return str_replace($float,floatval($value),$line);
}


    ?>

Now I'm stuck how to write the correct value inside the file in the right line?

I tried this:

fwrite($handle,implode(";",correctFloat($line)));

But it didn't work. How to re-write each line into the file in the right position with the correct float without losing data? Any idea?

:::EDIT:::

I also tried to use a temporary file:

$temp = tmpfile();
fputcsv($temp,correctFloat($line),';');
fwrite($handle,fread($temp, 1024));

but I didn't get a good result. nothing happened inside the file.

Example

Input :

Name;timestamp;.23
Name;timestamp;2,4578
Name;timestamp;1.23

Expected output:

Name;timestamp;0.23
Name;timestamp;2.4578
Name;timestamp;1.23

In this example: 2,4578 should be in the output : 2.4578 (I replace the comma with '.' using the function correctFloat($line) above )

New try:

$newline = correctFloat(array_combine($headers, $line));
array_push($newline,chr(10));
$l = implode(";",$newline);
fwrite($handle,$l);
rewind($handle);

Only the first value changes and then the file is refreshing without getting out of the loop.

  • 写回答

2条回答 默认 最新

  • duandeng2011 2017-02-14 12:49
    关注

    Requirements: Given a CSV input file then create an output file that has the float fields formatted correctly.

    How:

    • Read the input file one record at a time splitting it into fields
    • Format the floating point string into a valid string ny replacing comma with decimal point.
    • Apply some validation to the fields
    • format the fields as a valid output string (correctFloat)
    • append to the output file.

    Note: I have used test data so the validation is not checked. This code just formats the output from the input.

    Source code I used

    Code:

    Input / Output file names:

    define('DATA_FILE', 'Q42208643.dat');
    define('DATA_FILE_OUT', 'Q42208643.out.dat');
    

    Headers and Validation:

    // setup field names and validiation rules
    $headers = ['name',  'timestamp', 'floatValue',];
    
    $args = array(
                  'sensor_internal_id' => array('filter' => FILTER_VALIDATE_REGEXP,
                                                          'options' => array('regexp' => '/^[a-zA-Z0-9_:.()\/]*$/'), ),
    
                  'timestamp' => array('filter' => FILTER_CALLBACK,
                                       'options' => 'validateDate', ),
    
                   'value' => array('filter' => FILTER_VALIDATE_FLOAT),
            );
    

    Process input and output files:

    if (($handle = fopen(DATA_FILE, "r+")) !== false) {
    
        $fOut = fopen(DATA_FILE_OUT, "wb");
    
        while (($fields = fgetcsv($handle, 1024, ";")) !== false) {
    
            $fields[2] = str_replace(",", ".", $fields[2]); // ensure float sting is valid
    
            $namedFields = array_combine($headers, $fields);
            $result = filter_var_array($namedFields, $args);
    
            $outLine = correctFloat($fields);
            fwrite($fOut, $outLine . PHP_EOL);
        }
        fclose($handle);
        fclose($fOut);
    }
    

    functions:

    function validateDate($date)
    {
      if (!preg_match("/^\d{8}$/", substr($date, 0, 8))) {
          return false;
      }
      if (!checkdate(substr($date, 4, 2), substr($date, 6, 2), substr($date, 0, 4))) {
          return false;
      }
      if (substr($date, 8, 2) > 23 || substr($date, 10, 2) > 59 || substr($date, 12, 2) > 59) {
          return false;
      }
    
      return true;
    }
    
    
    function correctFloat($fields) {
      $fields[2] = floatval($fields[2]);
      return implode(';', $fields);
    }
    

    Sample input:

    122222;1487075470;.123
    233333;1487075470;2,345
    344444;1487075470;3.678
    

    Sample Output:

    122222;1487075470;0.123
    233333;1487075470;2.345
    344444;1487075470;3.678
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗
  • ¥15 钢筋实图交点识别,机器视觉代码
  • ¥15 如何在Linux系统中,但是在window系统上idea里面可以正常运行?(相关搜索:jar包)
  • ¥50 400g qsfp 光模块iphy方案
  • ¥15 两块ADC0804用proteus仿真时,出现异常
  • ¥15 关于风控系统,如何去选择