首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Ada双链接列表

如何使用Ada双链接列表
EN

Stack Overflow用户
提问于 2020-04-11 03:09:23
回答 2查看 563关注 0票数 2

我正在用Ada编程语言做一个学校项目。教授希望我们用一种我们不熟悉的语言来写作。我需要使用Ada双链接列表来编写文本编辑器程序。程序在调用时将接受一个可选的命令行参数,这将指定默认的文件名。如果该文件已经存在,则应将其内容加载到文本缓冲区中。保存该文件后,缓冲区的内容将转储到具有指定名称的文件中,从而覆盖任何现有文件。

例如,如果我输入

A-附加命令

你好

世界

该文件将有

你好

世界

附加到文档末尾

如果我打字

3 a

你好

世界

然后,在文档的第3行之后追加同一行。

这是我到目前为止编写的代码,但我也不知道如何使用string作为case语句的条件。

有人能帮我做这个项目吗?

代码语言:javascript
运行
复制
with Ada.Containers.Doubly_Linked_Lists;
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;


procedure main is
   package String_List is new Ada.Containers.Doubly_Linked_Lists(Unbounded_String);
   use String_List;
   --Userinput : String(1 .. 10) := (others => ' '); --This string length is 10
   Last: Integer; --This is use to count input string length
   currentAddress: Integer := 0;
   text : List; -- List is from Doubly_Linked_Lists
   type Userinput is (a, c, p, e);
   --size: Integer; --This is use to count input string length


   procedure Print(Position : Cursor) is -- this subprogram print all string from list
   begin
      Put_Line(To_String(Element(Position)));
      --Put_Line("K");
   end Print;



begin
   loop

      Put( Integer'Image (currentAddress) & " >> " );

      Get_Line(Userinput);

      case Userinput is

         when a =>
            Put( Integer'Image (currentAddress) & " >> " );
            Get_Line(Userinput);  
            text.Append(To_Unbounded_String(Userinput)); -- if letter is a add it to the doubly link list        

         when c =>      
            --text.Insert(Before => text.Find(To_Unbounded_String(Userinput)), New_Item => To_Unbounded_String( ? ));

         when p =>      
            text.Iterate(Print'access);
         when e =>      
            Put_Line("Program Exit");                     
            exit;
         when others =>
            Put_Line ("No command found ");   

      end case;

   end loop;

end main;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-11 16:22:19

实现应用程序的诀窍是将其分解为功能组件,并在一个单独的(系列)包中实现每个组件。例如,可以从以下几个方面开始:

  • 将命令的解析从其在文本缓冲区上的作用位置拆分。定义并实现具有以下规范的包(例如):

parser.ads

代码语言:javascript
运行
复制
package Parser is

   Parse_Error : exception;   

   type Command_Kind is (Insert, Delete, Clear);

   subtype Line_Number is Natural;   
   No_Line_Number : constant Line_Number := 0;

   type Command is record
      Kind : Command_Kind;
      Line : Line_Number;
   end record;      

   function Parse (Str : String) return Command;
   --  Parses the given string and returns a command data object on success.

end Parser;
  • 实现抽象文本缓冲区。您可能希望使用Indefinite_Vectors而不是Doubly_Linked_List作为您选择的容器,因为您将广泛地处理行号(与双链接列表相比,向量可以更容易地被索引)。定义并实现具有以下规范的包(例如):

text_buffers.ads

代码语言:javascript
运行
复制
with Ada.Containers.Indefinite_Vectors;

package Text_Buffers is

   type Text_Buffer is private;

   subtype Line_Number is Positive;   --  Different from Parsers.Line_Number!

   procedure Load 
     (Buffer   : in out Text_Buffer; 
      Filename : String);
   --  Loads a text file into the text buffer.

   procedure Save 
     (Buffer   : in out Text_Buffer;
      Filename : String);
   --  Saves a text buffer into a text file.

   function Line_Count 
     (Buffer : Text_Buffer) return Natural;
   --  Gets the number of lines in the buffer.

   function Get_Line
     (Buffer : Text_Buffer;
      Line   : Line_Number) return String;
   --  Gets the text of the given line.

   procedure Clear 
     (Buffer : in out Text_Buffer);
   --  Clears the text buffer.

   procedure Insert
     (Buffer : in out Text_Buffer; 
      Text   : String; 
      After  : Line_Number);
   --  Inserts line of text to the text buffer.

   procedure Delete
     (Buffer : in out Text_Buffer; 
      Line   : Line_Number);
   --  Deletes a line of text from the text buffer.

   --  ... other actions.   

private

   package Vector_String is 
     new Ada.Containers.Indefinite_Vectors (Line_Number, String);  
   use Vector_String;

   type Text_Buffer is new Vector with null record;

end Text_Buffers;
  • 使用包ParserText_Buffers构建最终的文本编辑器应用程序。我建议将应用程序逻辑(初始化和主循环)也放在一个单独的包中,并从Run调用Main (参见下面):

editor.ads

代码语言:javascript
运行
复制
package Editor is

   procedure Run (Filename : String);
   --  Runs the editor application.

end Editor;

editor.adb

代码语言:javascript
运行
复制
with Parser;
with Text_Buffers;

package body Editor is

   ---------
   -- Run --
   ---------

   procedure Run (Filename : String) is
   begin      
      -- Initialization & Program loop.
      null;
   end Run;      

end Editor;

main.adb

代码语言:javascript
运行
复制
with Ada.Command_Line;
with Editor;

procedure Main is
  Filename : String;
begin
   --  Process command line options, set Filename.
   Editor.Run (Filename);
end Main;
票数 2
EN

Stack Overflow用户

发布于 2020-04-11 08:34:59

不能使用String作为case语句(ARM 5.4(4))的“选择表达式”,因为它不是离散类型(大于实数或记录)。

您可以尝试使用枚举,如下面的示例(这就留下了如何处理像示例3 a这样的输入的问题):

代码语言:javascript
运行
复制
with Ada.Text_IO;
with Ada.IO_Exceptions;
procedure Alan is
   type Command is (A, C, P, E);
   package Command_IO is new Ada.Text_IO.Enumeration_IO (Command);
begin
   loop
      declare
         Cmd : Command;
      begin
         Command_IO.Get (Cmd);
         Ada.Text_IO.Skip_Line;
         Ada.Text_IO.Put_Line ("read " & Cmd'Image);                -- ' to sort out the not-fully-Ada-aware syntax highlighting
         case Cmd is
            when A => ...
            ...
            when E => exit;
         end case;
      exception
         when Ada.IO_Exceptions.Data_Error =>
            Ada.Text_IO.Put_Line ("unrecognised command");
      end;
   end loop;
end Alan;

通常情况下,我会use Ada.Text_IO;;而不是这里,为了清楚。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61151618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档