comp.lang.ada
 help / color / mirror / Atom feed
From: Ludovic Brenta <ludovic@ludovic-brenta.org>
Subject: Re: problems with interfacing c
Date: Fri, 28 Jan 2011 01:41:33 -0800 (PST)
Date: 2011-01-28T01:41:33-08:00	[thread overview]
Message-ID: <ba6ae9e9-79c9-435d-bf9d-112063e486fe@q36g2000yqn.googlegroups.com> (raw)
In-Reply-To: 85c958cc-8cd3-46be-b14d-3519ff207d87@b8g2000vbi.googlegroups.com

Staszek Goldstein wrote on comp.lang.ada:
> I am sending a solution to a problem to a site managing programming contests, and
> the stdin is in fact redirected to some text file with data. I do not know how
> big the data file will be, I know only the upper limit. Quick reading of the data is the
> key to success, and the two lines of C work very well for the purpose. I have not
> tried your solution, is it not going to cause constraint_error when it meets the end of the
> file?

If you really read from Standard_Input, there is no upper limit to the
size of the file, so you should not depend on one. i.e. your program
should work if you say:

$ yes | my_program

The proper way to read a potentially infinite amount of data from
Standard_Input is to read one character at a time, buffer the input
for processing, and discard the buffer from time to time so your
program runs in constant memory. The points in time where you discard
the buffer depend on the algorithm.

Like Dmitry, I strongly suggest you use Ada.Streams, not Ada.Text_IO,
because the latter is much slower (it does a lot of unnecessary
bookkeeping behind the scenes).

Here is a small example where I process the input buffer whenever it
is full and then discard it. I also do that when I reach the end of
the input stream. Note that I have not compiled this example, so it
may contain (intentional :)) bugs.

with Ada.IO_Exceptions;
with Ada.Text_IO;
with Ada.Strings.Bounded;
procedure My_Program is
   Current_Input : constant Ada.Text_IO.Text_Streams.Stream_Access :=
     Ada.Text_IO.Text_Streams.Stream (Ada.Text_IO.Current_Input);
   package Buffers is new Ada.Strings.Bounded.Generic_Bounded_Length
(Max => 100_000);

   procedure Process_And_Discard (Buffer : in out
Buffers.Bounded_String) is
   begin
      -- actual processing left as an exercise for the reader :)
      Buffers.Delete (Source => Buffer, From => 1, Through =>
Buffers.Max_Length);
   end Process_And_Discard;

   Buffer : Buffers.Bounded_String;
begin
   loop
      declare
          C : Character;
      begin
          Character'Read (Current_Input, C);
          if Buffers.Length (Buffer) = Buffers.Max_Length then --
buffer is full
             Process_And_Discard (Buffer);
          end if;
          Buffers.Append (Source => Buffer, New_Item => C);
      exception
          when Ada.IO_Exceptions.End_Error => -- end of stream reached
             Process_And_Discard (Buffer); -- process whatever we read
last
             exit;
      end;
   end loop;
end My_Program;

> The other question is - how to use the C bindings properly in such a case?

Don't.

--
Ludovic Brenta.



  parent reply	other threads:[~2011-01-28  9:41 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-20 20:21 problems with interfacing c Stoik
2011-01-20 20:56 ` Dmitry A. Kazakov
2011-01-20 21:31   ` Yannick Duchêne (Hibou57)
2011-01-20 23:03     ` Dmitry A. Kazakov
2011-01-21  0:46       ` Yannick Duchêne (Hibou57)
2011-01-21  9:33         ` Dmitry A. Kazakov
2011-01-28  0:39   ` Stoik
2011-01-28  5:24     ` Yannick Duchêne (Hibou57)
2011-01-28  9:41     ` Ludovic Brenta [this message]
2011-01-28  9:44     ` Dmitry A. Kazakov
2011-01-31 21:46       ` Stoik
2011-01-31 23:06         ` Edward Fish
2011-02-01  8:48         ` Dmitry A. Kazakov
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox