【问题标题】:Ada string comparisonAda 字符串比较
【发布时间】:2013-02-06 22:01:06
【问题描述】:

我是 Ada 的新手,目前正在尝试编写一个包含 if-else if 语句的简单程序。代码如下:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Year_Codes is

  Year : String(1..9) := "         ";
  CharsRead : Natural;

  function YearCode(Name : in String) return Integer is
  begin
    if(Name = "freshman")then
      return 1;
    elsif(Name = "sophomore")then
      return 2;
    elsif(Name = "junior")then
      return 3;
    elsif(Name = "senior")then
      return 4;
    else
      return 0;
    end if;
  end YearCode;


begin
  Put("Enter your academic year: ");           -- Prompt for input
  Get_Line(Year, CharsRead);                   -- Input
  Put( YearCode(Year) );                       -- Convert and output
  New_Line;
end Year_Codes;

每个答案我都得到 0。关于我做错了什么有什么意见吗?

【问题讨论】:

  • 你的 E-lisp 程序应该在一个单独的问题中。我已经回答了你的 Ada 问题;该答案与您的 E-lisp 程序无关。
  • 我想如果我问两个我会被骂但我会拿出来:|对不起
  • 我已编辑您的 Ada 代码以更正缩进并添加 withuse 子句。我还冒昧地更新了您的标题和标签(真正的问题是字符串比较,而不是 if 语句)。
  • 非常感谢。你已经提供了更多的帮助。

标签: string ada string-comparison


【解决方案1】:

对字符串的"=" 操作会比较整个字符串。如果用户输入的是"freshman",那么Name 的值将是"freshman ",而不是"freshman"。阅读Get_Line 过程的文档。

您可能应该将YearCode 传递给Year 字符串的切片,而不是整个字符串; CharsRead 告诉你该切片应该是什么。

具体来说,调用应该是:

Put( YearCode(Year(Year'First..CharsRead)) );

【讨论】:

  • 谢谢你为新生工作,但之后的其他人仍在注册 0。我的 ifels 语句有问题吗?
  • @user1998581:我自己试过了,效果很好;我输入senior 并打印4
  • 请注意,CharsRead 这个名字在这里有点误导。 Im RM,它被称为Last:这个变量包含输入缓冲区中写入的最后一个字符,而不是写入的字符数。当 Year'First 大于 1 时,差异变得(尤其)明显:正确的切片仍然是 Year(Year'First..Last)
  • 另外我注意到他的缓冲区只有 9 个字符长。这会起作用,但如果用户错误地输入了 10 个或更多的字符串,则可能会出现奇怪的行为。将缓冲区设置得过大(例如:256、1K 等)可能会更好。
【解决方案2】:

这是一个使用属性的不区分大小写的版本:

function YearCode(Name : in String) return Integer is
    Type Class is (Freshman, Sophmore, Junior, Senior);
begin
    Return 1 + Class'Pos(Class'Value(Name));  
exception
    When CONSTRAINT_ERROR => Return 0;
end YearCode;

【讨论】:

  • 在这里大 +1。这是我针对一组固定的允许命令词处理用户输入的首选方法。做更多的工作,您可以提出一个版本,它会根据请求自动打印允许的命令(例如在 contraint_error 处理程序中)。过去,我什至曾经有一些很好的通用代码,可以使用 DEC SMG$ 调用为给定的枚举类型自动创建菜单和处理菜单输入。
【解决方案3】:

在你的缓冲区中有那个额外的字符,在我看来你是在用 C 语言来考虑字符串。你需要阻止它。 在语言的所有内容中,字符串处理在 Ada 和 C 之间是最不同的。

虽然 C 字符串以 null 结尾,但 Ada 字符串不是。相反,Ada 字符串被假定为字符串数组对象的大小。这是一个简单的区别,但它会对您处理字符串的方式产生巨大的影响。

我在对How to I build a string from other strings in Ada? 的回答中对此进行了一些探讨,基本要点是,在 Ada 中,您总是尝试动态构建完美大小的字符串对象。

遗憾的是,Text_IO 输入是传统上很难做到这一点的地方,因为它基于字符串缓冲区的输入。在这种情况下,你不得不使用一个过大的字符串对象作为缓冲区,并使用返回的值作为缓冲区定义区域的结尾,正如 Keith 所示。

但是,如果您有新版本的编译器,您可以使用 Get_Line 的函数版本来修复它。只需将中间两行更改为:

Put( YearCode(Get_Line) );                       

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    相关资源
    最近更新 更多