【问题标题】:Second (independent) while loop not executing in Perl第二个(独立的)while 循环不在 Perl 中执行
【发布时间】:2016-10-12 04:05:18
【问题描述】:

我正在尝试使用 Perl 脚本使用两个独立的 while 循环读取两个单独的文件。我正在使用面向对象的方式来读取文件(模块 IO::File)。读取 file1 的第一个 while 循环运行良好,但读取 file2 的第二个 while 循环没有读取任何内容。我的代码如下,

 #!/usr/bin/perl
 use 5.18.0;
 use warnings;
 use IO::File;
 $file1="file1.dat";
 $file2="file2.dat";
 my $f1 = IO::File -> new("< $file1") or die "Cannot read file1: $!"; 
 my $f2 = IO::File -> new("< $file2") or die "Cannot read file2: $!";

 while ( $linef1 = $f1 -> getline() ){
      data extraction from file 1 
}
$f1 -> close;
while ( $linef2 = $f2 -> getline() ){
    data extraction from file 2
   }

我在第二个 while 循环中写了几个打印语句来查看它们是否正在执行。我发现打印语句没有执行,这意味着程序没有进入第二个 while 循环。这意味着第二个 while 循环的 getline() 语句可能有问题,但我不知道如何解决。任何帮助,将不胜感激。 编辑:为简洁起见,我在代码中省略了一些变量声明。

Edit2:这是我正在做的一个最小示例。

#!/usr/bin/perl
use 5.18.0;
use warnings;
use IO::File;

my $output_filename = $ARGV[0];
my $file = substr($output_filename,0,-4);
my $line;
my $linef;
my $foo = 0;
my $bar = 0;
my $fchk_filename = "hcho_fr.fchk";

my $fout = IO::File -> new("< $output_filename") or die "Cannot read log file: $!"; 
my $ffchk = IO::File -> new("< $fchk_filename") or die "Cannot read fchk file: $!";

 while ( $line = $fout -> getline() ){
    if ($line =~ /Initial\sParameters/){
      $foo++;
      print("Still in the first while loop.\n");
     }
  }

  print("First while loop completed.\n");
  $fout -> close;

  while ( $linef = $ffchk -> getline() ){
  print("Entered the second while loop.\n");
  if ( $linef =~ /Cartesian Gradient/ ){
    $bar++;
    print("Still in the second while loop.\n");
     }
   }

   print("Successfully executed.\n");

这段代码运行没有任何错误,并给了我以下输出。

   Still in the first while loop.
   Still in the first while loop.
   First while loop completed.
   Successfully executed.

【问题讨论】:

  • 它在我的机器上运行良好(Ubuntu 16.04,Perl 5.22)。虽然必须先添加一些 my 关键字才能使警告静音。
  • 我没有看到任何错误——我测试过,它工作正常(v5.10)。您的第一个循环是否完成 - 您是否尝试在循环之间打印?文件肯定没问题吗?您能否展示一个完整的示例以及一些简短的示例文件?
  • 一方面,您的“数据提取...”可能会让您陷入while 中的无限循环,或者立即退出第二个循环。
  • 您确定您的第二个文件hcho_fr.fchk 的大小不为零吗?
  • @tobiuchiha 不傻——你通过调试就搞定了,剩下的就是一点经验的问题了我们期望它“应该”是什么。

标签: perl oop while-loop io


【解决方案1】:

以下是一些想法:

很可能 - 第二个文件是否以空行开头?您是否有可能得到一个空的但真实的价值?也许更好地检查

while ( defined($linef = $ffchk -> getline()) ){
  print("Entered the second while loop.\n");
  if ( $linef =~ /Cartesian Gradient/ ){
    $bar++;
    print("Still in the second while loop.\n");
  }
}

只是为了确保您得到的是一个定义的值而不是一个可能为空的值。

如果您读取不同的文件会发生什么?还是与第一个循环相同的文件?确保它不是简单的东西,比如缺少换行符。

最后,您是否尝试过在代码中添加“$| = 1”以确保输出没有在某处缓冲?这是一个很长的镜头,但有时输出可能看起来好像没有显示,因为它位于缓冲区中,等待在它出现之前被刷新。我怀疑这里是否会发生这种情况,但这是绝对确定的好方法。

这些只是根据您所描述的一些随机想法。

【讨论】:

  • 空行 ("\n") 为真。如果整个文件由单字节 0 组成(后面不跟换行符),defined 唯一的帮助。
  • 他们是从文件中读取,而不是从管道中读取,所以没有可以放置$| = 1;的程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
相关资源
最近更新 更多