Reputation: 47
I am writing a school project to store string to the doubly linked list, but I don't know how to save the final list to a text file. I also what the user to choose the text file name. Can someone show me how to do that? Also for Ada can I have a not fixed-length string as input? Right now I set the string length to 5 but I really wanted to have a flexible length for the string. Below is my code thank you.
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;
with Ada.IO_Exceptions;
procedure main is
type Command is (A, C, P, E, M);
package Command_IO is new Ada.Text_IO.Enumeration_IO (Command);
package String_List is new Ada.Containers.Doubly_Linked_Lists(Unbounded_String);
use String_List;
Userinput : String(1 .. 5) := (others => ' '); --This string length is 5
InsertLocation : String(1 .. 5) := (others => ' '); --This string length is 5
text : List; -- List is from Doubly_Linked_Lists
F : File_Type;
begin
loop
declare
Cmd : Command;
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
Put_Line("*****************************");
Put_Line("*Enter A to add a text *");
Put_Line("*Enter C to insert a text *");
Put_Line("*Enter P the print text list*");
Put_Line("*Enter E the exit program *");
Put_Line("*Enter M to save the list *");
Put_Line("*****************************");
Put_Line(" ");
Put(">> ");
Command_IO.Get (Cmd);
Ada.Text_IO.Skip_Line;
Put_Line ("read " & Cmd'Image); -- ' to sort out the not-fully-Ada-aware syntax highlighting
Put_Line (" " );
case Cmd is
when a =>
Put_Line("Enter a text " );
Put(">> " );
Get(Userinput);
text.Append(To_Unbounded_String(Userinput)); -- if letter is a add it to the doubly link list
Put_line(" " );
when c =>
Put_Line("Enter a text location you want to insert " );
Put(">> " );
Get(Userinput);
Put_Line("Enter a text " );
Put(">> " );
Get(InsertLocation);
text.Insert(Before => text.Find(To_Unbounded_String(Userinput)), New_Item => To_Unbounded_String( InsertLocation ));
when p =>
text.Iterate(Print'access);
Put_line(" " );
when m =>
Put_Line("Save to file");
Create (F, Out_File, "file.txt");
Put_Line (F, "This string will be written to the file file.txt");
Close (F);
when e =>
Put_Line("Program Exit");
exit;
end case;
exception
when Ada.IO_Exceptions.Data_Error =>
Put_Line ("unrecognised command");
Put_Line (" ");
end;
end loop;
end main;
Upvotes: 2
Views: 178
Reputation: 3641
You look like you have all the parts. You can use Text_IO for writing to the file and you can use Unbounded_String to hold strings of any size. For reading in strings of any size, you can use the procedure Get_Line in Text_IO which returns a string of any length or if you really want to use Unbounded_Strings, you can use Ada.Text_IO.Unbounded_IO.Get_Line. I could also optionally suggest looking at Indefinite_Doubly_Linked_List instead of using Unbounded_String, depending on your use case.
For writing to file, just loop over the List and write each element to a file using Text_IO style functions.
Here is some scaffolding showing some of this.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Indefinite_Doubly_Linked_Lists;
use Ada.Containers;
procedure Hello is
package Lists is new Indefinite_Doubly_Linked_Lists(String);
Text : Lists.List;
begin
Put_Line("Hello, world!");
Put_Line("Enter a text:" );
declare
User_Input : String := Get_Line;
begin
Text.Append(New_Item => User_Input);
end;
Put_Line("Enter Text to Insert at:");
declare
Location : String := Get_Line;
begin
Put_Line("Enter New Text:");
declare
User_Input : String := Get_Line;
begin
Text.Insert(Before => Text.Find(Location), New_Item => User_Input);
end;
end;
-- Loop through list and write each element
for Line of Text loop
Put_Line(Line);
-- Write to file here using Text_IO file operations
end loop;
end Hello;
Side note, if you spend more time searching your data than you do creating your list, you can also look at Map packages. Ada has both hashed and ordered maps (with indefinite options as well).
Upvotes: 3
Reputation:
Looks like you are on the right path.
A couple of points :
Create
call.'Read
and 'Write
attributes, which are procedures you can overload with your own procedures to format the file however you wish. The default 'Write
attribute for a list will iterate over the whole List calling each element's own 'Write
procedure. (It may also insert information about the List you don't want, that's why it's overloadable...)Upvotes: 1
Reputation: 25491
A couple of observations:
(1) Although a String
is a fixed-length object, the length can be determined at initialisation:
declare
Str : constant String := Get_Line;
begin
...
You may have to be a bit creative about using the value in Str
outside its scope, the declare block. For example, if it’s the name of a file to be opened, the File_Type
object to be opened could be in an outer scope.
(2) If you want to read an integer, use Ada.Integer_Text_IO.Get
(followed by Skip_Line
, because the Get
terminates when the number has been read, leaving the rest of the line, including the terminator, in the input buffer)
Upvotes: 3