有没有办法将两个文本文件中的值读取为十六进制并将其总和打印到第三个文件中?
sym.txt
02 01 04 01
sym2.txt
04 0f 07 09
symout.txt
06 10 0b 0a
这就是我试过的
use strict;
use warnings;
use Data::Dumper;
open my $fh1, '<', 'sym.txt' or die $!;
open my $fh2, '<', 'sym2.txt' or die $!;
open my $out, '>', 'symout.txt' or die $!;
while ( !eof( $fh1 ) and !eof( $fh2 ) ) {
my $line1 = <$fh1>;
my $line2 = <$fh2>;
my @l1 = split /\s+/, $line1;
my @l2 = split /\s+/, $line2;
my @newvalues;
my $i = 0;
for ( @l1 ) {
push @newvalues, $_ + $l2[$i];
$i++;
}
print Dumper \@newvalues;
for ( my $i = 0; $i < @newvalues; $i++ ) {
$newvalues[$i] = sprintf( '%3x', $newvalues[$i] );
}
my $new = join( '', @newvalues );
print $out $new . "\n";
}
它打印十六进制值但不是全部打印,并且它不会从文件中读取十六进制,而是从文件中读取实际值。
答案 0 :(得分:3)
这类似于你所拥有的,但使用较少的中间内容,并且我使用map
进行列表转换而不是for
循环。
use strict;
use warnings;
open(my $in1, '<', 'in1.txt') or die $!;
open(my $in2, '<', 'in2.txt') or die $!;
open(my $out, '>', 'out.txt') or die $!;
while (!eof($in1) && !eof($in2)) {
my @vals1 = split(' ', <$in1>);
my @vals2 = split(' ', <$in2>);
my @sums = map { hex($vals1[$_]) + hex($vals2[$_]) } 0..$#vals1;
print $out join(' ', map { sprintf('%.2x', $_) } @sums) . "\n";
}
close($in1);
close($in2);
close($out);
答案 1 :(得分:0)
这对你有用
它可能更复杂,因为它遵循您的示例并且满足具有不同数量的值的记录并且将任何缺少的元素默认为零
我还允许每个总共最多三个十六进制数字,因为0xFF + 0xFF是0x1FE
请注意,在空格上拆分字符串的正确方法是使用单个文字空间作为第一个参数。 SubscriptionClient.OnMessage
错了
此程序需要将两个输入文件的路径作为命令行上的参数
split /\s+/
use strict;
use warnings 'all';
open my $fh1, '<', $ARGV[0];
open my $fh2, '<', $ARGV[1];
open my $fh_out, '>', 'symout.txt' or die $!;
until ( eof $fh1 or eof $fh2 ) {
my @l1 = map hex, split ' ', <$fh1>;
my @l2 = map hex, split ' ', <$fh2>;
my $n = @l2 > @l1 ? @l2 : @l1;
my @sum = map {
no warnings 'uninitialized';
$l1[$_] + $l2[$_];
} 0 .. $n-1;
@sum = map { sprintf '%03X', $_ } @sum;
print { $fh_out } "@sum\n";
}
要将每个总和截断为8位,您应该将赋值更改为006 010 00B 00A
到此
@sum
您还可以将 my @sum = map {
no warnings 'uninitialized';
( $l1[$_] + $l2[$_] ) & 0xFF;
} 0 .. $n-1;
中的格式说明符更改为sprint
,因为永远不会有任何大于两位的十六进制值