用PHP读取二进制文件

用PHP读取二进制文件,php,c++,structure,Php,C++,Structure,这是使用的“C++”结构 struct gross { char date[11]; char ac[128]; char type[5]; float mvalue; float netraw; float netfer; char stat[128]; float firr; float acb; }; 这是使用GCC编译器编译时生

这是使用的“C++”结构

struct gross
    {
        char date[11];
        char ac[128];
        char type[5];
        float mvalue;
        float netraw;
        float netfer;
        char stat[128];
        float firr;
        float acb;
    };
这是使用GCC编译器编译时生成的二进制文件的内容

1995年12月12日d美国12.23 34.12 90.12费用12 56.12 1998年1月1日美国52.23 54.12 10.12费用92 16.12 31/12/1999美国52.23 54.12 10.12费用92 16.12 31/12/1999 d us 12.23 34.12 90.12费用12 56.12 2000年1月1日美国52.23 54.12 10.12费用92 16.12 2000年1月1日z us 12.23 34.12 90.12费用12 56.12 2010年12月31日美国52.23 54.12 10.12费用92 16.12 2010年12月31日d美国12.23 34.12 90.12费用12 56.12

PHP编码读取上述二进制文件的内容

echo "<table>";
while (!feof($f)) {

  if ($s = fread($f, 292)) {

        $nn = unpack('a11date/a128ac/a5type/fmvalue/fnetraw/fnetfer/a128stat/ffirr/facb', $s);

        echo "<td>" . $nn[date] ."</td>";
        echo "<td>" . $nn[ac] . "</td>";
        echo "<td>" . $nn[type] . "</td>";
        echo "<td>" . $nn[mvalue] . "</td>";
        echo "<td>" . $nn[netraw] . "</td>";
        echo "<td>" . $nn[netfer] . "</td>";
        echo "<td>" . $nn[stat] . "</td>";
        echo "<td>" . $nn[firr] . "</td>";
        echo "<td>" . $nn[acb] . "</td>";
        echo "</tr>";
 }
}
        echo "</table>";
fclose($f);
?>
echo”“;
而(!feof($f)){
如果($s=fread($f,292)){
$nn=拆包('a11date/a128ac/a5type/fmvalue/fnetraw/fnetfer/a128stat/ffirr/facb',$s);
回显“$nn[日期]”;
回显“$nn[ac]”;
回显“$nn[类型]”;
回显“$nn[mvalue]”;
回显“$nn[netraw]”;
回显“$nn[netfer]”;
回显“$nn[stat]”;
回显“$nn[firr]”;
回显“$nn[acb]”;
回声“;
}
}
回声“;
外国法郎(f美元);
?>
这是我从上面的代码中得到的。我得到的是第二个和第七个字段中的大量垃圾值。并且精度超过了浮点字段的精度。如何解决这个问题

1995年12月12日d¸³M·g·ew·dw·ew·r·w·w;w·SpP·ip·dw·ew·5w·Og· 美国12.22999542236 34.119998931885 90.120002746582费用

1998年1月1日· 美国52.22999542236 54.119998931885 10.119999885559费用

1999年12月31日a¸³M·g·ew·dw·ew·r·w·w·w·w·Og· 美国52.22999542236 54.119998931885 10.119999885559费用

1999年12月31日d¸³M·g·ew·dw·ew·r·w·w·w·w·Og· 美国12.22999542236 34.119998931885 90.120002746582费用

2000年1月1日· 美国52.22999542236 54.119998931885 10.119999885559费用

2000年1月1日z¸³M·g·ew·dw·ew·r·w·w·w·w·Og· 美国12.22999542236 34.119998931885 90.120002746582费用

2010年12月31日· 美国52.22999542236 54.119998931885 10.119999885559费用

2010年12月31日· 美国12.22999542236 34.119998931885 90.120002746582费用


在PHP的
pack
unpack
中,格式化代码
a
代表NUL填充的字符串。在这种情况下,第二个和第七个字段似乎没有NUL填充;它们只有NUL来指示字符串结束的位置,后面是随机数据

要获取NUL之前的字符串部分,可以使用
substr
strpos

$input = "a\000b"; // string with embedded NUL 
$output = substr($input, 0, strpos($input, "\000"));
var_dump($output); // string(1) "a"

浮点字段具有正确的值,您在C程序输出中看到的值将被舍入。要在PHP中执行相同操作,您可以使用
sprintf
例如:

$input = 16.120000839233;
$output = sprintf("%.2f", $input);
var_dump($output); // string(5) "16.12"

是的,因为你解包的第二个参数是“a128ac”和手动(http://jp2.php.net/manual/en/function.pack.php)表示“a”代表“NUL填充字符串”,但您可能需要“a”,即“空格填充字符串”。您看到的是垃圾,因为找不到正确的终止符。

这可能是编译器输出该文件的方式与php脚本打开该文件的方式在字符编码上的差异。请尝试找出这是什么类型的编码,以及您是否可以在指定如何读取该文件的同时在php中打开该文件。