将一个float的正确值写入csv文件 [英] Write the correct value of a float to a csv file
问题描述
在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
) - 输出文件。
注意:我已使用测试数据,因此不检查验证。此代码仅格式化输入的输出。
代码:
输入/输出文件名:
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.
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屋!