如何制作Perl’;s system()使用科学符号格式化参数?

如何制作Perl’;s system()使用科学符号格式化参数?,perl,floating-point,scientific-notation,Perl,Floating Point,Scientific Notation,在我的Perl程序中,我尝试运行另一个使用system用C编写的命令。该命令需要几个参数:一个字符串、一个浮点、两个整数、一对浮点和另一个字符串。我正在运行这个作为 my $arg1="electron"; my $arg2=0.511; # more definitions system("./fermions $arg1 $arg2 $arg3 $arg4 " . "$arg5 $arg6 \"string\" > outfile.out"); 我需要将$arg5更改为

在我的Perl程序中,我尝试运行另一个使用
system
用C编写的命令。该命令需要几个参数:一个字符串、一个浮点、两个整数、一对浮点和另一个字符串。我正在运行这个作为

my $arg1="electron";
my $arg2=0.511;
# more definitions
system("./fermions $arg1 $arg2 $arg3 $arg4 " .
       "$arg5 $arg6 \"string\" > outfile.out");
我需要将
$arg5
更改为几个不同的浮点值。我通过设置
$arg5=“1.0e5”
然后在for循环中运行if语句来将值更改为字符串,从而使其工作。我想能够做这个作为浮动,并尝试

system("./fermions $arg1 $arg2 $arg3 $arg4 " .
       "%e $arg6 \"string\" >outfile.out",
       $arg5);

但这并不奏效。还有其他选择吗,或者只有我的if语句选项吗?

如果要使用printf表示法(如“%e”),则需要使用Perl
sprintf
内置。否则,您只需将“%e”作为文本参数传递。

重要提示:您应该始终检查Perl函数的返回值,以确定命令是否失败

使用Perl格式化浮点值,如下代码所示。是的,您可以不使用该命令作为格式说明符,但是如果该命令在其他地方有%字符,您可能会得到令人惊讶的结果。使用两个步骤更安全

#! /usr/bin/env perl

use strict;
use warnings;

my @float_values = (1.0e5, 3.14159, 2.71828);

for my $f (@float_values) {
  my $arg5 = sprintf "%e", $f;

  system(qq[./fermions $arg5 "string" >> outfile.out]) == 0
    or warn "$0: fermions failed";
}
如果您不熟悉语法,它的工作方式类似于双引号字符串,但不同的分隔符意味着您不必在命令中转义双引号

请注意,出于排版目的,我省略了其他参数,但您可以将它们与
$arg5
的值一起插入。另一个微妙的变化是切换到
>
进行追加,而不是
进行删除

使用费米子的替代品

#! /usr/bin/env perl
$" = "][";
warn "[@ARGV]\n";
同时运行的两个程序的输出为

[1.000000e+05][string] [3.141590e+00][string] [2.718280e+00][string]
请考虑使用<代码>系统列表< /代码>或<代码>系统{程序}列表< /代码>。如果有一天,经过多次重构,
$arg2
变成了
“rm-rf/”
,这将更加安全。您将无法使用shell输出重定向,但您始终可以自己打开
outfile.out
并将其复制到标准输出或在shell脚本中包装
/fermions
,以捕获输出。明白。我将为此修改我的代码,但在这一点上,我提出了这个问题,以供将来使用。
#! /usr/bin/env perl

use strict;
use warnings;

my @float_values = (1.0e5, 3.14159, 2.71828);

for my $f (@float_values) {
  my $arg5 = sprintf "%e", $f;

  my $pid = fork;
  if (defined $pid) {
    if ($pid == 0) {
      my $path = "outfile.out";
      open STDOUT, ">>", $path or die "$0: open $path: $!";
      exec "./fermions", $arg5, "string" or die "$0: exec: $!";
    }
    else {
      local $!;
      my $pid = waitpid $pid, 0;
      warn "$0: waitpid: $!" if $pid == -1 && $!;
      warn "$0: fermion exited " . ($? >> 8) if $?;
    }
  }
  else {
    die "$0: fork: $!";
  }
}