使用perl创建一个简单的计算器

2023-12-24

我需要用 Perl 设计一个简单的计算器,名为 ex1.pl,只需+, -, *, and /功能。以下是我所拥有的。

while (@ARGV>0) {
    if ($_=~m/(\d+)\s(.)\s(\d+)/) {
        if ($2 == "+") {
            print "$1 + $3\n";
        }   
        elsif ($2 == "-") {
            print "$1 - $3\n";
        }   
        elsif ($2 == "*") {
            print "$1 * $3\n";
        }   
        elsif ($2 == "/") {
            if ($3 == 0 ) { 
                print "$1 cannot be divided by 0\n";
            }   
            else {
                print "$1 / $3\n";
            }   
        }   
        else {
            print "operator not identified\n";
        }
    }   
    else {
        print "syntax error\n";
    }   
}

例如,如果我输入./ex1.pl 5 + 2,一直报错



Use of uninitialized value in pattern match (m//) at line 4
  

直到我按 ctrl + c。谁能帮我找出我哪里做错了?


循环while(@ARGV>0)不分配给$_正则表达式匹配已完成,因此没有任何内容匹配,代码转到else. Also, @ARGV永远不会被清空,因此代码处于无限循环中。

其余代码在语法上是正确的,但必须重写,因为它会迭代输入中的单词,而编写正则表达式来处理整个输入。对于该正则表达式,处理需要依次采用每个参数,或者需要将命令行组装成字符串。

下面进一步发布了对问题中代码的进一步评论。

让我提供一种不同的方法

use warnings;
use strict;
use feature 'say';

use Scalar::Util qw(looks_like_number);

my ($n1, $op, $n2) = @ARGV;

my $re_oper = qr{^(?:\+|-|\*|/)$};  #/

usage() if @ARGV != 3
    or not looks_like_number($n1) or not looks_like_number($n2)
    or $op !~ $re_oper;

my %calculate = ( 
    '+' => sub { return $_[0] + $_[1] },
    '-' => sub { return $_[0] - $_[1] },
    '*' => sub { return $_[0] * $_[1] },
    '/' => sub {
        die "Can't divide by zero" if $_[1] == 0;
        return $_[0] / $_[1] 
    },
);

say $calculate{$op}->($n1, $n2);

sub usage { 
    say STDERR 
        "Usage: $0 number operator number\n",
        "The \"operator\" is one of +,-,\\*,/\n",
        "Note that multiplication (*) must be escaped at command line";
    exit;
}

使用复制参数并检查错误looks_like_number from 标量::实用程序 https://perldoc.perl.org/5.8.9/Scalar/Util.html和一个正则表达式。我使用以下方法准备正则表达式模式qr操作员 http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators因此单独指定,使测试、维护和扩展更容易。

然后我们定义一个以匿名子例程作为值的哈希(它们是代码参考, 参见项目4. in 在 perlref 中进行引用 https://perldoc.perl.org/perlref.html#Making-References),通常称为调度表 https://en.wikipedia.org/wiki/Dispatch_table#Perl_implementation。因此不需要级联if-elsif系列:对于给定的键(运算符),相应的值被取消引用并且该子例程运行。

为了简洁起见,在一个语句中检查参数,但最好逐一检查,以便能够向用户报告所发生的确切错误(并引用导致该错误的输入)。


有关已发布代码的更多细节

  • 操作员捕获的模式需要使用进行测试string比较,做了什么eq运算符,不与==。看看这些在佩洛普 https://perldoc.perl.org/perlop.html#Equality-Operators. So if ($2 eq '+') etc

  • 默认情况下,正则表达式匹配是针对$_多变的 https://perldoc.perl.org/perlvar.html#General-Variables,Perl 中许多事物的默认值。所以没必要写if ($_ =~ /.../)只是if (/.../)。阅读证明(隐式)使用的合理性的理由要清楚得多$_

  • 正则表达式模式\d匹配所有类型的数字,包括 Unicode。更好的利用[0-9]

  • 图案\s允许one“空白”字符。如果将命令行参数组合成一个字符串$input = join ' ', @ARGV;(所以要使用正则表达式)那么就可以了。但留出更多空间仍然更安全\s+.

  • The .在正则表达式中匹配任何one特点。这限制了脚本未来可能的扩展,例如权力提升**(ETC)。考虑允许数字之间存在任何字符,这是可行的,因为它们在命令行上由空格分隔。

  • 用于数字的模式仅匹配正整数(同时如果前面有负号,则意外地允许第一个整数为负数)。上面的代码通过使用来解决这个问题looks_like_number,它利用 Perl 的所有功能来识别数字。


问题的原始版本 had while (<>)for 循环,答案由此开始:

The “钻石”运算符(<>) https://perldoc.perl.org/perlop.html#I/O-Operators从命令行提交的文件中读取

输入来自<>来自标准输入,或来自命令行上列出的每个文件。

所以你的输入5 + 2被视为文件名5 and + and 2,并且此类文件不存在。

该运算符更加复杂,可以在文档中阅读有关内容。

可以在以下位置访问命令行参数@ARGV https://perldoc.perl.org/perlvar.html#ARGV,所以最简单的解决方案是替换while (<>) with foreach (@ARGV)然后逐项处理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用perl创建一个简单的计算器 的相关文章

  • 如何将 cpanminus 与本地 CPAN::Mini 一起使用?

    我已经创建了自己的 CPAN 本地副本minicpan http search cpan org rjbs CPAN Mini 1 111007 bin minicpan并设法重新配置 cpan 来使用它 太棒了 但是我将如何使用它cpan
  • 在 Objective-C 中使用 perl?

    CPAN 有大量非常有用的库 除了将它们移植到 Objective C 之外 是否还有在 iOS 上将 Perl 代码嵌入到 Objective C 中的方法 我对使用特别感兴趣电子表格 阅读 http kobesearch cpan or
  • 从 shell 脚本调用 Perl,如何将返回值从 Perl 传递到 shell?

    我成功地从 shell 脚本调用 Perl 脚本 现在我想将 Perl 脚本的返回值传递给 shell 脚本 指示它是否成功 我该怎么做呢 只需使用适当的退出值退出 Perl 脚本即可 exit exit value exit 0 if p
  • 在 Perl 中组装 XML

    我需要对 NetApp 文件管理器进行 API 调用 我知道我需要发送什么原始 XML
  • 如何从 Perl 中的 Subversion 预提交挂钩访问提交的文件?

    我需要执行以下操作 用 Perl 编写预提交钩子 Hook 应检查所有提交的文件是否存在某些文本 如果未找到该文本则失败 基本上 我需要一个读取正在提交的文件的 Perl 钩子示例 我真的在寻找一些代码量最少的优雅解决方案 笔记 钩子应该使
  • 在 Perl 中优雅地确定系统架构

    我正在寻找一种简单的方法来确定 Perl 5 中的系统是 32 位还是 64 位 我已阅读perlvar来回翻阅手册页 并没有发现包含系统 CPU 架构的变量 编译 Perl 的 CPU 架构将足够接近 这是我最接近的 chomp my a
  • Perl 删除目录中的所有文件

    我怎样才能删除allPerl 中目录中的文件 不删除目录 我的主机只允许最多 250 000 个 文件 而我的 tmp 文件夹会在所有会话 cookie 运行的情况下快速填充 250 000 个 qouta 在这种情况下我无法删除 tmp
  • 为什么 **sort** 不在每台机器上进行相同的排序?

    使用相同的sort具有相同输入的命令在不同的机器上产生不同的结果 我该如何解决这个问题 The man page http developer apple com documentation Darwin Reference ManPage
  • Perl 中如何释放内存?

    我的代码如下所示 my var my var new while 1 while my k v each var a sub v var A map var var new keys var new var new B sub a sub
  • 如何在没有循环的情况下初始化哈希中的值?

    我正在尝试找出一种无需经过循环即可初始化哈希的方法 我希望使用切片来实现这一点 但它似乎没有产生预期的结果 考虑以下代码 usr bin perl use Data Dumper my hash hash currency symbol B
  • linux + ksh + 向下舍入或向上舍入 - 浮点数

    在我的 ksh 脚本中 我只需要计算整数 有时我会得到浮点数 例如 3 49 或 4 8 等 所以我需要根据以下规则将浮点数转换为整数 示例 3 49 will be 3 2 9 will be 3 4 1 will be 4 23 51
  • 使用 Perl 循环 JSON [重复]

    这个问题在这里已经有答案了 我是 Perl 的新手 想要循环这个 JSON 数据并将其打印到屏幕上 我怎样才能做到这一点 arr Year 2012 Quarter Q3 DataType Other 3 Environment STEVE
  • 如果文件没有行尾字符,则 wc -l 不计算文件的最后一个

    我需要计算 unix 文件的所有行数 该文件有 3 行 但是wc l仅给出 2 个计数 我知道它不计算最后一行 因为它没有行尾字符 任何人都可以告诉我如何计算这一行吗 grep c返回匹配行的数量 只需使用一个空字符串 作为您的匹配表达式
  • 基于 Unix ASCII 的命令行图表/绘图工具

    有没有好的命令行 UNIX 图表 绘图 绘图工具 我正在寻找能够在 ASCII 图表上绘制 xy 点的东西 澄清一下 我正在寻找能够以 ASCII 格式输出图形 如 ascii art 风格 的东西 这样我就可以在交互式 shell 会话中
  • 如何使用 Net::SSH::Perl 和公钥?

    我正在尝试使用Net SSH Perl使用公钥与此代码进行连接 my ssh Net SSH Perl gt new host debug gt 1 die 我将密钥放在 root ssh id rsa 和 root ssh identit
  • 正则表达式删除块注释也删除 * 选择器

    我正在尝试使用 bash 从 css 文件中删除所有块注释 我有以下 sed 命令的正则表达式 sed r s w s w d 这可以很好地去除块注释 例如 This is a comment this is another comment
  • 如何在 Perl 中使用 use strict 一次一行处理多行字符串?

    我正在尝试找出 PBP 批准的正确方法来一次一行处理多行字符串 许多 Perl 编码人员建议将多行字符串视为文件句柄 除非您在脚本中使用 use strict 否则它可以正常工作 然后 您会收到编译器发出的警告 提示在使用严格引用时无法使用
  • 迭代哈希数组

    我编写了下面的例程 迭代哈希值 0 7 并打印出每个哈希值中特定键的值 我需要获取每个哈希中 b4 的值 我想取消 0 7 当存在不同数量的哈希值时使用更智能的东西 例如 有时只有 2 个 也可能有 160 个 my out decode
  • 安装python启动文件

    我如何安装pythonstartup文件 以便它在命令上运行 例如python myfile py 我尝试将其安装到我的 home myuserUbuntu的目录 但它说我没有足够的权限 此外 不同的地方交替说它应该全部大写或全部小写 前面
  • Perl 和 Unix 如何以相同的顺序对 Unicode 字符串进行排序?

    我正在尝试获取 Perl 和 GNU Linuxsort 1 程序就如何对 Unicode 字符串进行排序达成一致 我在跑sort with LANG en US UTF 8 在Perl程序中我尝试了以下方法 use Unicode Col

随机推荐