将一个float的正确值写入csv文件 [英] Write the correct value of a float to a csv file

查看:214
本文介绍了将一个float的正确值写入csv文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在csv文件中,我有这样的结构:

  Name; timestamp; floatValue 
Name;时间戳; floatValue
名称;时间戳; floatValue
...

代码,我检查行中的每个值,我过滤它们,然后我想通过调用函数 floatval 更正浮点值,因为我有错误的值有时像:。 904或2,454,并使用此函数返回正确的格式化的函数。

 <?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);

函数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);
}


?>

现在我卡住了如何在正确的文件中写入正确的值?



我试过:

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

但它没有工作。 如何使用正确的浮动将每行重新写入正确的位置,而不会丢失数据?
任何想法?


::: EDIT :::


我也尝试使用临时文件:

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

但我没有得到好的结果。



输入:

/ em>

 名称;时间戳; .23 
名称;时间戳; 2,4578
名称; timestamp; 1.23

预期输出:



 名称;时间戳; 0.23 
名称;时间戳; 2.4578
名称;时间戳; 1.23

在此示例中:2,4578应该在输出中:2.4578(我使用函数替换逗号correctFloat($ line)上面)


新尝试:



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

只有第一个值更改,然后文件正在刷新而不退出循环。

解决方案

要求:给定一个CSV输入文件,然后创建一个输出文件,其中的float字段格式正确。



如何:




  • 一次读取一个记录的输入文件,将其分割为

  • 将浮点字符串格式化为有效字符串ny用小数点替换逗号。

  • 字段

  • 将这些字段格式化为有效的输出字符串( correctFloat

  • 输出文件。



注意:我已使用测试数据,因此不检查验证。此代码仅格式化输入的输出。



源代码I使用



代码:



输入/输出文件名:

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

标题和验证:

  //设置字段名称和验证规则
$ 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),
);

处理输入和输出文件:

  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]); //确保float sting有效

$ namedFields = array_combine($ headers,$ fields);
$ result = filter_var_array($ namedFields,$ args);

$ outLine = correctFloat($ fields);
fwrite($ fOut,$ outLine。PHP_EOL);
}
fclose($ handle);
fclose($ fOut);
}

功能: b

 函数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);
}

示例输入:



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



示例输出:



  122222; 1487075470; 0.123 
233333; 1487075470; 2.345
344444; 1487075470; 3.678


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.

解决方案

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

这篇关于将一个float的正确值写入csv文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆