From: "G.B." <bauhaus@futureapps.invalid>
Subject: Re: Creating an empty file with Ada.Text_IO
Date: Tue, 25 Aug 2015 18:45:08 +0200
Date: 2015-08-25T18:45:08+02:00 [thread overview]
Message-ID: <mri5vb$g3u$1@dont-email.me> (raw)
In-Reply-To: <1c1a3b38-4810-4002-b4f5-ec09b5f97041@googlegroups.com>
On 25.08.15 17:26, Maciej Sobczak wrote:
>
>> procedure Write_String_To_File (File_Name : in String; S : in String) is
>> A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
>> F : Ada.Streams.Stream_IO.File_Type;
>> begin
>> -- convert S to stream elements
>> for I in S'Range loop
>> A (Ada.Streams.Stream_Element_Offset (I)) :=
>> Ada.Streams.Stream_Element (Character'Pos (S (I)));
>> end loop;
>
> Before anybody uses it in a rocket - there is no provision above that S'First will be 1 and the indices might not be compatible in the above assignment.
>
> Correct version is:
>
> for I in S'Range loop
> A (Ada.Streams.Stream_Element_Offset (I - S'First + 1)) :=
> Ada.Streams.Stream_Element (Character'Pos (S (I)));
> end loop;
>
> And there are actually several ways to write it.
> Now this procedure can write String slices that do not begin at index 1.
>
> (Frankly, this part of Ada is inherently error-prone. I stumble on it repeatedly.)
>
subtypes seem helpful. If S can be made of a constraint subtype,
too, then an unchecked conversion should work, too. (Does, using GNAT).
with Ada.Characters.Latin_1;
with Ada.Streams.Stream_IO;
procedure Test is
subtype S_E_Offset is Ada.Streams.Stream_Element_Offset;
use type S_E_Offset;
-- static assert:
Is_Positive_in_S_E_Offset : constant array (Boolean) of Integer :=
(
S_E_Offset'First > S_E_Offset (Positive'First) => 123,
S_E_Offset'Last >= S_E_Offset (Positive'Last) => 123
);
procedure Write_String_To_File (File_Name : in String; S : in String) is
subtype Index is S_E_Offset
range S_E_Offset (S'First) .. S_E_Offset (S'Last);
A : Ada.Streams.Stream_Element_Array (Index);
F : Ada.Streams.Stream_IO.File_Type;
begin
-- convert S to stream elements
for I in S'Range loop
A (S_E_Offset (I)) :=
Ada.Streams.Stream_Element (Character'Pos (S (I)));
end loop;
-- create a stream file and write the content (which might be empty)
Ada.Streams.Stream_IO.Create (F, Ada.Streams.Stream_IO.Out_File,
File_Name);
Ada.Streams.Stream_IO.Write (F, A);
Ada.Streams.Stream_IO.Close (F);
end Write_String_To_File;
begin
-- empty file:
Write_String_To_File ("file1.txt", "");
-- file with one, non-terminated line:
Write_String_To_File ("file2.txt",
String'(22 => 'a',
23 => 'b',
24 => 'c'));
-- file with "one line and a half":
Write_String_To_File ("file3.txt",
"abc" & Ada.Characters.Latin_1.LF & "xyz");
end Test;
next prev parent reply other threads:[~2015-08-25 16:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-24 14:16 Creating an empty file with Ada.Text_IO Maciej Sobczak
2015-08-24 16:15 ` Dmitry A. Kazakov
2015-08-25 8:20 ` Maciej Sobczak
2015-08-25 15:26 ` Maciej Sobczak
2015-08-25 16:18 ` J-P. Rosen
2015-08-25 16:45 ` G.B. [this message]
2015-08-24 18:51 ` AdaMagica
2015-08-24 22:22 ` Randy Brukardt
2015-08-25 0:06 ` Dennis Lee Bieber
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox