忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 1884 | 回复: 5

read 读多了 [复制链接]

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-09-21 19:15 |显示全部楼层
求助,我有一个txt文档,类似于以下格式。每连续的4个数字是一个16进制数,这四个数字里,前两个是低位后两位是高位。
类似于0000,0081,0101,0182这样。

111.txt
00008100010182010202820203038403040485040505860506068706070788070808890809098A090A0A8B0A0B0B8C0B0C0C8D0C0D0D8E0D0E0E8F0E0F0F900F0010
00004000A10001017101D2014202A302230394031404950405057505E6055606D7064707B8073808C9085909EA096A0ADB0A3B0B9C0B0C0C8D0C1D0DAE0D4E0EDF0E
000091003101D2015202F30284031404A5042505A6052606A70617078807080899083909CA094A0ABB0A1B0B7B0BDC0B4C0CBD0C3D0DBE0D4E0EDF0E5F0FC00F0010
00007000E1005101D2014202B3022303A40314048504F5047505E6055606C7064707B8072808990819098A09FA096A0AEB0A5B0BCC0B3C0CBD0C2D0D9E0D0E0E7E0E


我想得到每个对应的十进制数字。要转成十进制,再除以16,得到如下:
gam.txt
0   8.0625   16.0625   24.125   32.125   40.125   48.1875   56.25   64.25   72.3125   80.3125   88.375   96.375   104.4375   112.4375   120.5   128.5   136.5625   144.5625   152.625   160.625   168.6875   176.6875   184.75   192.75   200.8125   208.8125   216.875   224.875   232.9375   240.9375   249   256
0   4   10.0625   16.0625   23.0625   29.125   36.125   42.1875   50.1875   57.25   65.25   73.3125   80.3125   87.3125   94.375   101.375   109.4375   116.4375   123.5   131.5   140.5625   149.5625   158.625   166.625   173.6875   179.6875   185.75   192.75   200.8125   209.8125   218.875   228.875   237.9375
0   9.0625   19.0625   29.125   37.125   47.1875   56.25   65.25   74.3125   82.3125   90.375   98.375   106.4375   113.4375   120.5   128.5   137.5625   147.5625   156.625   164.625   171.6875   177.6875   183.6875   189.75   196.75   203.8125   211.8125   219.875   228.875   237.9375   245.9375   252   256
0   7   14.0625   21.0625   29.125   36.125   43.1875   50.1875   58.25   65.25   72.3125   79.3125   87.3125   94.375   101.375   108.4375   116.4375   123.5   130.5   137.5625   145.5625   152.625   159.625   166.625   174.6875   181.6875   188.75   195.75   203.8125   210.8125   217.875   224.875   231.875

以上是原帖内容,以下是我的代码:
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. open(my $FHr, '<', 'z:\\f');
  5. my ($buf, $last);
  6. my $DBG = 1;
  7. while(read($FHr, $buf, 2)){
  8.     if($buf =~ /\R+/){
  9.         print("\n{$buf}\n") if($DBG);
  10.         next;
  11.     }
  12.     if(defined $last){
  13.         print(hex("$buf$last") / 16, " ");
  14.         $last = undef;
  15.         next;
  16.     }
  17.     $last = $buf;
  18. }
  19. close($FHr);
复制代码

执行结果 在遇到第一个换行符之前都正确。遇到换行符后 read 读多了。


请大神指点,谢谢。

论坛徽章:
120
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07巳蛇
日期:2014-05-09 16:43:18巨蟹座
日期:2014-10-23 17:48:38子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59
发表于 2017-09-21 22:57 |显示全部楼层
回复 1# sunzhiguolu

Don't forget the newline(0d 0a)


C:\Users\Jason Lee\tmp>type 111.txt
00008100010182010202820203038403040485040505860506068706070788070808890809098A09
0A0A8B0A0B0B8C0B0C0C8D0C0D0D8E0D0E0E8F0E0F0F900F0010
00004000A10001017101D2014202A302230394031404950405057505E6055606D7064707B8073808
C9085909EA096A0ADB0A3B0B9C0B0C0C8D0C1D0DAE0D4E0EDF0E
000091003101D2015202F30284031404A5042505A6052606A70617078807080899083909CA094A0A
BB0A1B0B7B0BDC0B4C0CBD0C3D0DBE0D4E0EDF0E5F0FC00F0010
00007000E1005101D2014202B3022303A40314048504F5047505E6055606C7064707B80728089908
19098A09FA096A0AEB0A5B0BCC0B3C0CBD0C2D0D9E0D0E0E7E0E

C:\Users\Jason Lee\tmp>perl hex_div16.pl
................................................................................
....................................................0A
................................................................................
....................................................0A
................................................................................
....................................................0A
................................................................................
....................................................

C:\Users\Jason Lee\tmp>type hex_div16.pl
#!/usr/bin/perl
use strict;
use warnings;

open(my $FHr, '<', '111.txt');
#binmode $FHr;
my ($buf, $last);
my $DBG = 1;
while(read($FHr, $buf, 1)){
    if($buf =~ m/([\x01-\x1F])/){
        printf("%02X\n", ord$1);
        next;
    }
    print ".";
}
close($FHr);




# the result with binmode
C:\Users\Jason Lee\tmp>perl hex_div16.pl
................................................................................
....................................................0D
0A
................................................................................
....................................................0D
0A
................................................................................
....................................................0D
0A
................................................................................
....................................................

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-09-22 09:37 |显示全部楼层
回复 2# jason680
谢谢您指点。

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my (@tmp, @out, $buf);
  5. open(my $FHr, '<', 'z:\\f');
  6. binmode($FHr);
  7. while(read($FHr, $buf, 1)){
  8.     if($buf =~ /\R+/){
  9.         print(join(' ', splice(@out, 0)), "\n") if($buf =~ /\n/);
  10.         next;
  11.     }
  12.     next if(push(@tmp, $buf) < 4);
  13.     $out[@out] = hex(join('', @tmp[-2 .. 1])) / 16;
  14.     @tmp = ();
  15. }
  16. close($FHr);
复制代码

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-09-22 09:50 |显示全部楼层
我还有个小疑问想请教下,谢谢。
从结果看 binmode 影响了 m/pattern/ 对 \r 的匹配, 导致字节错位。
如下方式 却不会收到影响。
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my (@tmp, @out, $buf);
  5. open(my $FHr, '<', 'z:\\f');
  6. #binmode($FHr);
  7. while(read($FHr, $buf, 1)){
  8.         if(ord($buf) == 0x0a or ord($buf) == 0x0d){
  9.                 print(join(' ', splice(@out, 0)), "\n") if(ord($buf) == 0x0a);
  10.                 next;
  11.         }
  12.         next if(push(@tmp, $buf) < 4);
  13.         $out[@out] = hex(join('', @tmp[-2 .. 1])) / 16;
  14.         @tmp = ();
  15. }
  16. close($FHr);
复制代码


大神,能否解释一下 这是个啥情况?

论坛徽章:
120
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07巳蛇
日期:2014-05-09 16:43:18巨蟹座
日期:2014-10-23 17:48:38子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59
发表于 2017-09-22 13:00 |显示全部楼层
回复 4# sunzhiguolu

NO ISSUE ??  but your code had some bug



C:\Users\Jason Lee\tmp>perl hex_div16_bin.pl
0 8.0625 16.0625 24.125 32.125 40.125 48.1875 56.25 64.25 72.3125 80.3125 88.375
96.375 104.4375 112.4375 120.5 128.5 136.5625 144.5625 152.625 160.625 168.6875
176.6875 184.75 192.75 200.8125 208.8125 216.875 224.875 232.9375 240.9375 249
256
0 4 10.0625 16.0625 23.0625 29.125 36.125 42.1875 50.1875 57.25 65.25 73.3125 80
.3125 87.3125 94.375 101.375 109.4375 116.4375 123.5 131.5 140.5625 149.5625 158
.625 166.625 173.6875 179.6875 185.75 192.75 200.8125 209.8125 218.875 228.875 2
37.9375
0 9.0625 19.0625 29.125 37.125 47.1875 56.25 65.25 74.3125 82.3125 90.375 98.375
106.4375 113.4375 120.5 128.5 137.5625 147.5625 156.625 164.625 171.6875 177.68
75 183.6875 189.75 196.75 203.8125 211.8125 219.875 228.875 237.9375 245.9375 25
2 256
0 7 14.0625 21.0625 29.125 36.125 43.1875 50.1875 58.25 65.25 72.3125 79.3125 87
.3125 94.375 101.375 108.4375 116.4375 123.5 130.5 137.5625 145.5625 152.625 159
.625 166.625 174.6875 181.6875 188.75 195.75 203.8125 210.8125 217.875 224.875 2
31.875

C:\Users\Jason Lee\tmp>type hex_div16_bin.pl
#!/usr/bin/perl
use strict;
use warnings;

my (@tmp, @out, $buf);
open(my $FHr, '<', '111.txt');
binmode($FHr);
while(read($FHr, $buf, 1)){
    if($buf =~ /\R+/){
        print(join(' ', splice(@out, 0)), "\n") if($buf =~ /\n/);
        next;
    }
    next if(push(@tmp, $buf) < 4);
    $out[@out] = hex(join('', @tmp[-2 .. 1])) / 16;
    @tmp = ();
}
close($FHr);

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-09-22 17:27 |显示全部楼层
本帖最后由 sunzhiguolu 于 2017-09-22 17:31 编辑

回复 5# jason680
您是说下面这种情况吗?


  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my (@tmp, @out, $buf);
  5. open(my $FHr, '<', 'z:\\f');
  6. binmode($FHr);
  7. while(read($FHr, $buf, 1)){
  8.     if($buf =~ /\R+/){
  9.         print(join(' ', splice(@out, 0)), "\n") if($buf =~ /\n/);
  10.         next;
  11.     }
  12.     next if(push(@tmp, $buf) < 4);
  13.     $out[@out] = hex(join('', @tmp[-2 .. 1])) / 16;
  14.     @tmp = ();
  15. }
  16. close($FHr);
  17. print(join(' ', splice(@out, 0)), "\n") if(@out);
复制代码

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP