免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2000 | 回复: 6
打印 上一主题 下一主题

如何防止循环中元素被修改 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-11-16 10:16 |只看该作者 |倒序浏览
在循环中如何来防止数组中的元素被修改
如id文件为:
   3608,7754321
    12345,343608
oldgrp文件为:
   apache:12345
代码1 循环时,会发生
   apache:343608
    apache:347754321  (这一行是多出来的) 是由于循环数组的数据被修改了,又参与了循环
代码2 偶增加了临时变量,结果是正确的。

对于什么时候会修改循环原数据,我不是很明白。请高人指点下。

代码1:
#!/usr/bin/perl


use File::Basename;
open(SRCFILE,"<oldgrp");
open(IDFILE,"<id");
@idarr=<IDFILE>;

while( $grpline=<SRCFILE>){

&nbsp;&nbsp;&nbsp;&nbsp;foreach $each(@idarr)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chomp $each;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;($sid,$nid)=split /,/,$each;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($grpline =~ /$sid/)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$grpline=~ s/$sid/$nid/;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "$grpline";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}



代码2:
#!/usr/bin/perl


use File::Basename;
open(SRCFILE,"<oldgrp");
open(IDFILE,"<id");
@idarr=<IDFILE>;

while( $grpline=<SRCFILE>){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;foreach $each(@idarr)
&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chomp $each;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;($sid,$nid)=split /,/,$each;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $gline=$grpline;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($gline =~ /$sid/)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#print "$grpline\n";

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$gline=~ s/$sid/$nid/;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print $gline;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;}
}

论坛徽章:
0
2 [报告]
发表于 2007-11-16 10:37 |只看该作者
乱得一塌糊涂.

1.
对代码1:
补上use strict;
补上use warnings;
补上my, 运行结果只有一行:
apache:343608


2.
@idarr=<IDFILE>;
在这里就chomp @idarr;  多好, 何必每次循环都去搞.

3.
if($grpline =~ /$sid/)
      {
        $grpline=~ s/$sid/$nid/;
         print "$grpline";
     }
为什么不写成
if($grpline=~ s/$sid/$nid/;)
      {
         print "$grpline";
     }

论坛徽章:
0
3 [报告]
发表于 2007-11-16 12:32 |只看该作者
1.
对代码1:
补上my, 运行结果只有一行:
apache:343608

这my加在哪里(我测试都是一样)?     示例不做任何修改,只有几个记录时不会出现我所说的情况(也是apache:343608这个结果),当处理1000多条记录时就会出现。

论坛徽章:
0
4 [报告]
发表于 2007-11-16 12:44 |只看该作者
每使用一个新变量, 定义的地方就用my

缩小下出问题的数据范围吧, 用二分法.
如果没法缩小范围, 把2个文件当做附件贴上来.
如果没法贴上来, mail给我.

论坛徽章:
0
5 [报告]
发表于 2007-11-16 14:28 |只看该作者
我用代码2可以解决,不会出现这种情况,是正确的。代码2使用了临时变量。
    foreach $each(@idarr)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chomp $each;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;($sid,$nid)=split /,/,$each;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($grpline =~ /$sid/)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$grpline=~ s/$sid/$nid/;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "-1-";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "$grpline";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "-2-\n";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$grpline= "0";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}


id文件:
12345,343608
3608,7754321
grp文件:
apache:12345

输出,
apache:343608
apache:347754321

测试的时候发现,问题是出现在foreach 循环中,当$grpline被修改后,又在foreach 中循环,如果后面加一个$grpline="0" 类似置空,就可以。

[ 本帖最后由 mantou 于 2007-11-16 15:01 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2007-11-16 14:45 |只看该作者
  1. if($grpline=~ s/$sid/$nid/;)
  2.       {
  3.          print "$grpline";
  4.      }
复制代码


提示语法不对哦, 就是;这里 。纠正一下,这个; 是多余的。

[ 本帖最后由 mantou 于 2007-11-16 14:50 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-11-16 15:41 |只看该作者
原来你是这个意思... 偶没话说

建议把标题改一下吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP