From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,a0833bbed8752e1f X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!news1.google.com!news.glorb.com!newsfeeds.sol.net!posts.news.twtelecom.net!nnrp3.twtelecom.net!not-for-mail From: "Matthew Heaney" Newsgroups: comp.lang.ada References: Subject: Re: variable lenght strings Date: Thu, 21 Oct 2004 19:14:19 -0400 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.2180 X-RFC2646: Format=Flowed; Response X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 Message-ID: <417842cd$0$74191$39cecf19@news.twtelecom.net> Organization: Time-Warner Telecom NNTP-Posting-Date: 21 Oct 2004 23:14:21 GMT NNTP-Posting-Host: e68e561f.news.twtelecom.net X-Trace: DXC=?S39H=CafiK\o7M8kQj6MMOj3YM9`=aH>k5;YbS4 "Marius Amado Alves" wrote in message news:mailman.46.1098398641.10401.comp.lang.ada@ada-france.org... >> 1) Is it possible to use Get_Line with Unbounded and/or Bounded >> Strings? > > Not in the standard, but subprograms like those are usually around, e.g. > in the GNAT Library, or end up being written in house. > >> 2) If not, how should usei input be managed when lines length isn't >> known a priori? > > There's a way using the standard Get_Line, explained in AdaPower. Mario is probably referring to an article I posted to CLA a few years' ago, and which is now archived at the adapower website. The basic idea is this: algorithms that consume input from a stream need a way a identify when all of the input has been consumed. Typically this is done using a special value that you know is outside the range of normal values, e.g. declare I : Natural; begin loop Get (Stream, I); exit when I = 0; --the special value ... -- do something with I end loop; end; Text_IO.Get_Line works just like this, except that it's not obvious what the termination condition is: declare Line : String (1 .. 81); Last : Natural; begin loop Get_Line (Line, Last); .. -- do something with Line (1 .. Last); exit when ??? end loop; end; The termination condition is as follows: you know that you've consumed the entire line when Last < Line'Last. We can now write: declare Line : String (1 .. 81); Last : Natural; begin loop Get_Line (Line, Last); .. -- do something with Line (1 .. Last); exit when Last < Line'Last; end loop; end; Typically you know what a normal line length is, so you declare Line with a length of Max + 1. (That's why Line'Last is 81 in the examples above.) Now that you know the termination condition, the next problem is deciding how to handle a line of input that is longer than your buffer. You can either handle it as an error, or just copy the buffer into an expandable string buffer such as Unbounded_String. If you want, you can use recursion to read the line, and return the string as a function result: declare function Get_Line (N : Positive := 80) return String is Line : String (1 .. N + 1); Last : Natural; begin Get_Line (Line, Last); if Last < Line'Last then return Line (1 .. Last); else return Line & Get_Line (2 * N); end if; end Get_Line; Line : constant String := Get_Line; begin This avoids the loop, and having to store intermediate results in a buffer.