You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl文本二进制互转脚本丢失10.0000数据问题求助

问题原因分析

你的问题核心出在txt2bin.pl的打包逻辑错误,导致10这个数值没有被正确处理,同时反向转换的bin2txt.pl也存在对应问题,具体拆解如下:

1. txt2bin.pl的核心错误

当你执行$line =~ s/\.0000//;后,得到的是类似"137 136 133 136 10 134 0 132 132"的字符串,但紧接着直接把这个字符串传给pack("C*", $line)——这里Perl会把字符串拆分成单个字符(包括空格、数字字符),然后将每个字符的ASCII码值打包成字节,而不是把每个数字串解析成数值后打包。

举个例子:原数据中的10.0000变成10,但在字符串里是两个字符'1'(ASCII 49)和'0'(ASCII 48),这会被打包成两个字节,而不是一个值为10的字节;后续即使反向转换,也根本还原不出原本的10.0000。

2. bin2txt.pl的对应问题

因为打包时错误地把字符ASCII存成了字节,反向转换时的$data =~ s/(.{1})/unpack("C*",$1).".0000 \n"/eg;逻辑也不对:它把每个字节解析成ASCII值,然后拼接成字符串,但这和你原本想要的“还原数值”完全不匹配,而且每个字节后都加换行,导致输出格式混乱。

修正后的脚本

修正版txt2bin.pl

my $file = $ARGV[0];
my $fileout = $file.".bin";
if($file eq "-h" or $file eq "-help" or $file eq "") {
    print "Usage : txt2bin.pl file_in\n";
    print " file_out = file_in.bin\n";
    print "This script converts a txt file to a binary file\n";
} else {
    print "File in = $file\n";
    print "File out = $fileout\n";
    open(FILE,"<$file") or die $!;
    open(FILEOUT,">$fileout") or die $!;
    binmode FILEOUT;
    while(defined(my $line=<FILE>)) {
        chomp($line);
        # 先分割成单个数据项,再去除每个项的.0000并转成整数
        my @values = map { s/\.0000$//; int($_) } split /\s+/, $line;
        # 过滤掉超出无符号8位范围的数值(0-255),避免无效字节
        @values = grep { $_ >=0 && $_ <=255 } @values;
        syswrite FILEOUT, pack("C*", @values);
    }
    close(FILE);
    close(FILEOUT);
}

关键改动:

  • 用split /\s+/, $line将每行数据分割成独立的数字项
  • 通过map去除每个项的.0000并转换成整数
  • 添加grep过滤非法数值,保证打包的是有效的无符号8位字节
  • 传递数值列表@values给pack("C*"),而非原始字符串

修正版bin2txt.pl

my $file = $ARGV[0];
my $fileout = $file.".txt";
if($file eq "-h" or $file eq "-help" or $file eq "") {
    print "Usage : bin2txt.pl file_in\n";
    print " file_out = file_in.txt\n";
    print "This script converts a binary file to a txt file\n";
} else {
    print "File in = $file\n";
    print "File out = $fileout\n";
    undef $/; # 一次性读取整个二进制文件
    open(FILE,"<$file") or die $!;
    open(FILEOUT,">$fileout") or die $!;
    binmode FILE;
    my $data = <FILE>;
    # 解析所有字节为数值,再拼接成指定格式的字符串
    my @values = unpack("C*", $data);
    my $output = join(" ", map { sprintf("%.4f", $_) } @values);
    syswrite FILEOUT, $output . "\n";
    close(FILE);
    close(FILEOUT);
}

关键改动:

  • 直接用unpack("C*", $data)得到所有字节对应的数值列表
  • 用sprintf("%.4f", $_)还原成.0000结尾的格式
  • 用join将数值拼接成空格分隔的字符串,保持原数据的格式
验证效果

用你的测试数据:

137.0000 136.0000 133.0000 136.0000 10.0000 134.0000 0.0000 132.0000 132.0000

执行perl txt2bin.pl test.txt生成test.txt.bin,再执行perl bin2txt.pl test.txt.bin,得到的输出会和原数据完全一致,包括原本丢失的10.0000项。

内容的提问来源于stack exchange,提问作者dalex78

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:33:21