时间:2021-07-01 10:21:17 帮助过:20人阅读
不过很Faint的事情发生了,不知道是strpos的bug还是substr的bug(其实测试一下就知道,懒得试),有些字符串没问题,有些字符串却只能得到空值(即$name == ”)。很是郁闷,后来找了个strtok函数,这下没有问题了.
难为大家看了那么多,下面写个完整的php读取二进制数据流(C语言结构体struct数据)文件的示例代码:
首先是C的struct定义示例,为了演示,我就写个简单点的,实际对照上面那个$format格式表应该没有问题:
代码如下:
struct BIANBIAN {
char name[10];
char pass[33];
int age;
unsigned char flag;
};
比如有个“file.dat”文件,内容就是上面的N个BIANBIAN结构体构成的。读取的php代码:
代码如下:
//下面根据struct确定$format,注意int类型跟机器环境有关,我的32位Linux是4个长度
$format = 'a10name/a33pass/iage/Cflag';
//确定一个struct占用多少长度字节,如果只是读取单个结构体这是不需要的
$length = 10 + 33 + 4 + 1;
//也可以用fopen + fread + fclose,不过file_get_contents因为可以mmap,效率更高
$data = file_get_contents('file.dat', 'r');
for ($i = 0, $c = strlen($data); $i < $c; $i += $length) {
$bianbian = unpack("$format", $data);
//reference传递是php 5才支持的,如果用php4,得用其他办法
foreach ($bianbian as &$value) {
if (is_string($value)) {
$value = strtok($value, "\0");
}
}
print_r($bianbian);
}
?>
pack应该跟unpack相反。
顺便附上生成结构体文件的C语言代码:
代码如下:
#include
#include
struct example
{
char name[10];
char pass[33];
int age;
unsigned char flag;
};
int main()
{
example test;
example read;
FILE *fp;
test.age = 111;
test.flag = 10;
strcpy(test.name, "Hello World!");
strcpy(test.pass, "zbl110119");
fp = fopen("file.dat", "w+");
if (!fp)
{
printf("open file error!");
return -1;
}
rewind(fp);
fwrite(&test, sizeof(example), 1, fp);
rewind(fp);
fread(&read, sizeof(example), 1, fp);
printf("%d, %s\n", read.age, read.name);
fclose(fp);
return 0;
}