Ada:如何获取用户输入并将其填充到一个字符串(1..10),剩余部分用空格填充

9

我已经定义

subtype String10 is String(1..10);

我正在尝试在不手动输入空格的情况下获取键盘输入。我尝试使用get_line(),但它似乎不会在输出get_put()命令之前等待输入,并且我认为它只会保留之前字符串中的内容而不填充空格。

我知道并且已经使用了Bounded_String和Unbounded_String,但我想知道是否有一种方法可以使其正常工作。

我尝试为此编写一个函数:

--getString10--
procedure getString10(s : string10) is
   c : character;
   k : integer;
begin
   for i in integer range 1..10 loop
      get(c);
      if Ada.Text_IO.End_Of_Line = false then
         s(i) := c;
      else
         k := i;
         exit;
      end if;
   end loop;

   for i in integer range k..10 loop
      s(i) := ' ';
   end loop;
end getString10;

但是,在这里,我知道s(i)不起作用,而且我也不认为

"if Ada.Text_IO.End_Of_Line = false then" 

我希望它能够做到我期望的事情,但它只是一个占位符,而我在寻找实际的解决方法。

我已经搜索了几个小时,但Ada文档不像其他语言那样易于获取或清晰。我找到了很多关于获取字符串的信息,但并不是我正在寻找的。


1
将“true”和“false”的等值比较并不特别清晰。不要写成if Ada.Text_IO.End_Of_Line = false then,而是直接写成if not Ada.Text_IO.End_Of_Line then。(虽然我认为你也不需要使用End_Of_Line。) - Keith Thompson
2个回答

7

在调用Get_Line之前,只需使用空格对字符串进行预初始化。

这是我刚刚编写的一个小程序:

with Ada.Text_IO; use Ada.Text_IO;
procedure Foo is
    S: String(1 .. 10) := (others => ' ');
    Last: Integer;
begin
    Put("Enter S: ");
    Get_Line(S, Last);
    Put_Line("S = """ & S & """");
    Put_Line("Last = " & Integer'Image(Last));
end Foo;

我运行它时得到的输出:

Enter S: hello
S = "hello     "
Last =  5

另一种可能性是,在进行 Get_Line 调用之后,将剩余部分设置为空格,而不是预先初始化字符串:

with Ada.Text_IO; use Ada.Text_IO;
procedure Foo is
    S: String(1 .. 10);
    Last: Integer;
begin
    Put("Enter S: ");
    Get_Line(S, Last);
    S(Last+1 .. S'Last) := (others => ' ');
    Put_Line("S = """ & S & """");
    Put_Line("Last = " & Integer'Image(Last));
end Foo;

对于非常大的数组,后一种方法可能更有效,因为它不会两次分配字符串的初始部分,但实际上这种差异不太明显。


谢谢。我不确定为什么我没有想到预先初始化它。"(others => ' ')"是用空格填充S吗?到目前为止,我只在情况结构中使用过它,所以我不确定它还能做什么。 - user1279914
2
@user1279914:请参阅4.3.3 数组聚合 - trashgod
1
是的,在数组聚合中的 others 子句指的是所有未明确指定的元素。如果只有一个 others 子句,它就指代了数组的所有元素。 - Keith Thompson

3
作为替代方案,可以使用function Get_Line,它返回一个固定长度的String,该字符串“具有下限为1和上限为读取的字符数”。示例Line_By_Line使用从文件中读取的变体。如果需要,您可以使用procedure MoveSource字符串复制到Target字符串;该过程默认情况下自动填充空格。
附加说明:例如,此Line_Test使用*进行填充,并在右侧默默地截断长行。
with Ada.Integer_Text_IO;
with Ada.Strings.Fixed;
with Ada.Text_IO;

procedure Line_Test is
   Line_Count : Natural := 0;
   Buffer: String(1 .. 10);
begin
   while not Ada.Text_IO.End_Of_File loop
      declare
         Line : String := Ada.Text_IO.Get_Line;
      begin
         Line_Count := Line_Count + 1;
         Ada.Integer_Text_IO.Put(Line_Count, 0);
         Ada.Text_IO.Put_Line(": " & Line);
         Ada.Strings.Fixed.Move(
            Source  => Line,
            Target  => Buffer,
            Drop    => Ada.Strings.Right,
            Justify => Ada.Strings.Left,
            Pad     => '*');
         Ada.Integer_Text_IO.Put(Line_Count, 0);
         Ada.Text_IO.Put_Line(": " & Buffer);
      end;
   end loop;
end Line_Test;

我尝试使用get_line(),但它总是在等待输入之前打印以下put()。实际上,我正在从键盘获取输入,但有时也会使用输入文件。我会看看是否可以使用Move()使其正常工作。谢谢。 - user1279914
1
如果您遇到了这里描述的问题,请在此处联系我。如果您更新了代码,请告诉我。 - trashgod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接