Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Converting Type Characters to type string

2,842 views
Skip to first unread message

jedivaughn

unread,
Mar 30, 2008, 4:04:56 PM3/30/08
to
Hi,
I am looking for a way to convert a group of characters to a string.
For the program I am writing I am having the user input a group of
characters and comparing them. But I also need the characters in the
form of a string later on so I can use

int := Integer'Value(str);

How would I go about doing this? From the little bit I've founding
searching this I think I may need to use the ada.character.handeling
package. But on looking through this

http://www.infeig.unige.ch/support/ada/gnatlb/a-chahan.html

I can't find out how to do what I want. I am fairly new to Ada so if
you could give some examples of how you would do this I would really
appreciate it.

Thanks,
John

Pascal Obry

unread,
Mar 30, 2008, 4:19:43 PM3/30/08
to jedivaughn
jedivaughn a écrit :

> I am looking for a way to convert a group of characters to a string.
> For the program I am writing I am having the user input a group of
> characters and comparing them. But I also need the characters in the
> form of a string later on so I can use
>
> int := Integer'Value(str);

Looks like bad C habit to me :)

In Ada a String is defined as:

type String is array (Positive range <>) of Character;

So in your case you have something like this:

C : Character;

Get (C);

To get characters from user. Now to store them. Let's say you are going
to check 10 characters max:

Str : String (1 .. 10);
Index : Natural := 0;

To store each character:

Get (C);

Index := Index + 1;
Str (Index) := C;

At the end, Str (1 .. Index) contains all the characters entered by the
user as a string. Looks like this is what you are looking for, right?

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595

jedivaughn

unread,
Mar 30, 2008, 5:08:53 PM3/30/08
to
number 1 thank you so much for the fast response. But when I try your
suggestion and use say "1234" for the input I get the number 1, a few
spaces, and then some smiley faces. not exactly what I was hoping
for :) . Here's my code if that's any help.

with ada.text_IO, ada.integer_text_IO;

procedure integers is

index : natural :=0;
char : character;
str : string (1..10);

begin

ada.text_IO.put("Please enter a few Integers ");
ada.text_IO.get(char);

Index := Index + 1;

Str(Index) := Char;
ada.text_IO.put(str);

end integers;

Once again thanks so much for your help
- John

jimmaure...@worldnet.att.net

unread,
Mar 30, 2008, 5:28:11 PM3/30/08
to

Your example contains no loop, so it only gets a single character.

Ada strings are not null terminated like C strings. They are fixed
length data items.
A proper output of the character you collected is

Ada.Text_IO.Put(Str(1..Index));

Jim Rogers

Ludovic Brenta

unread,
Mar 30, 2008, 5:38:31 PM3/30/08
to
jedivaughn writes:
> number 1 thank you so much for the fast response. But when I try your
> suggestion and use say "1234" for the input I get the number 1, a few
> spaces, and then some smiley faces. not exactly what I was hoping
> for :) . Here's my code if that's any help.
>
> with ada.text_IO, ada.integer_text_IO;
>
> procedure integers is
>
> index : natural :=0;
> char : character;
> str : string (1..10);
>
> begin
>
> ada.text_IO.put("Please enter a few Integers ");
> ada.text_IO.get(char);
>
> Index := Index + 1;
> Str(Index) := Char;
> ada.text_IO.put(str);
^^^

Of course. Pascal said that "Str (1 .. Index)" contains the user input
as a string, not "Str" which contains exactly 10 characters no matter
how many the user typed.

> end integers;
>
> Once again thanks so much for your help
> - John

--
Ludovic Brenta.

Georg Bauhaus

unread,
Mar 30, 2008, 5:48:32 PM3/30/08
to

On Sun, 2008-03-30 at 14:08 -0700, jedivaughn wrote:
> number 1 thank you so much for the fast response. But when I try your
> suggestion and use say "1234" for the input I get the number 1, a few
> spaces, and then some smiley faces. not exactly what I was hoping
> for :) . Here's my code if that's any help.

Do I understand correctly that you want "1234" to be 4 integers?
In that case there is a loop missing.

> with ada.text_IO, ada.integer_text_IO;
>
> procedure integers is
>
> index : natural :=0;
> char : character;
> str : string (1..10);

str : string (1..10) := (1..10 => '*'); -- to see the effect

jedivaughn

unread,
Mar 30, 2008, 7:52:58 PM3/30/08
to
Thanks for the suggestions but I'm not quite sure how I would apply
these to my program can you give me an example in code?

Thanks for your patience
John

georg...@gmail.com

unread,
Mar 30, 2008, 11:04:38 PM3/30/08
to

procedure Test_Get is

Str : String (1 .. 10) := (others => ' ');
Index : Natural := 0;
C : Character;

begin

while index < Str'Last loop
Ada.Text_IO.Get (C);
-- This check can be different according to your needs:
exit when not Ada.Characters.Handling.Is_Digit (C);


Index := Index + 1;

Str (Index) := C;
end loop;
Ada.Text_IO.Put_Line (Str);

end Test_Get;

But I would rather use Get_Line instead of Get to get entire string
and then figure out what to do with it.

George.

tmo...@acm.org

unread,
Mar 31, 2008, 12:00:17 AM3/31/08
to
I'd use Last instead of Index. Then it's clear that Str(1 .. Last) is
what was typed in.

Ludovic Brenta

unread,
Mar 31, 2008, 4:54:24 AM3/31/08
to
As a matter of general principle, I always use a for loop when
traversing an array:

procedure Get_Digits (Result : out String; Last : out Natural);
-- Reads at most Result'Length characters from standard input. Stops
-- after the first character that is not a decimal digit.
-- On output, Result (Result'First .. Last) contains the digits from
stdin;
-- Last may be zero, indicating no digits entered (i.e. one character
that
-- is not a digit was read).

procedure Get_Digits (Result : out String; Last : out Natural) is
begin
Last := Result'Last; -- be optimistic
for Index in Result'Range loop
Ada.Text_IO.Get (Result (Index));
if not Ada.Characters.Handling.Is_Digit (Result (Index)) then
Last := Index - 1;
exit;
end if;
end loop;
end Get_Digits;

procedure Test_Get is
Str : String (1 .. 10);
Last : Natural;
begin
Get_Digits (Result => Str, Last => Last);
Ada.Text_IO.Put_Line (Str (1 .. Last));
end Test_Get;

--
Ludovic Brenta.

Dmitry A. Kazakov

unread,
Mar 31, 2008, 5:59:30 AM3/31/08
to
On Mon, 31 Mar 2008 01:54:24 -0700 (PDT), Ludovic Brenta wrote:

> As a matter of general principle, I always use a for loop when
> traversing an array:
>
> procedure Get_Digits (Result : out String; Last : out Natural);
> -- Reads at most Result'Length characters from standard input. Stops
> -- after the first character that is not a decimal digit.
> -- On output, Result (Result'First .. Last) contains the digits from stdin;
> -- Last may be zero, indicating no digits entered (i.e. one character that
> -- is not a digit was read).

(or none, on End_Error, Data_Error etc)

Such Get_Digits is not composable, without a sort of "unget," which
Ada.Text_IO does not have.

I believe it was a bad (FORTRAN?) idea to intermix I/O with parsing /
syntax analysis. Though it had one theoretical advantage of being able to
deal with lines of an unlimited length, in real life that never worked
anyway. (Like in your example, it would not).

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

Jean-Pierre Rosen

unread,
Mar 31, 2008, 6:59:28 AM3/31/08
to
Dmitry A. Kazakov a écrit :

> Such Get_Digits is not composable, without a sort of "unget," which
> Ada.Text_IO does not have.
>

Fortunately. If you want to avoid reading an extra character, use
Look_Ahead.

--
---------------------------------------------------------
J-P. Rosen (ro...@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr

jedivaughn

unread,
Mar 31, 2008, 9:50:32 AM3/31/08
to
The only problem I'm having is that I don't want to have to add a
space or another character to the end of my string of numbers. As long
as I set str : strin (1..999) := (others -> ' '); I can get all the
characters I want but they have to be followed by something other then
for a digit. Is there a way to get an input of a length unknown
without having to take an extra character? 0ne user suggested the
look_ahead procedure if that would help solve this how would I use
that?


Thanks,
- John

Ludovic Brenta

unread,
Mar 31, 2008, 10:11:07 AM3/31/08
to

Generally there are two ways of doing text input: fixed-width and
variable-width. In fixed-width form, the user must type exactly the
number of digits *you* want (no more, no less) but there is no need
for an extra character. This is really only useful when reading from a
file instead of the keyboard. In variable-width form, the user types
as many characters as *they* want, but they also have to insert a
terminating character. Usually, that character is Line Feed (produced
with the ENTER key). If that's what you want, you may want to call
Ada.Text_IO.Get_Line then traverse the resulting string looking for
digits.

See also http://www.it.bton.ac.uk/staff/je/adacraft/ch02.htm#2.6

--
Ludovic Brenta.

Dmitry A. Kazakov

unread,
Mar 31, 2008, 10:21:36 AM3/31/08
to

Can you tell us what do you want to achieve?

Normally, you would read a source line using Get_Line of Ada.Text_IO. Then
you would process the obtained string. The former is clear. What is about
the latter? What do you want to parse? Integer numbers?

with Ada.Text_IO; use Ada.Text_IO;
with Strings_Edit.Integers; use Strings_Edit.Integers;

procedure Numeric_Input is
begin
loop
Put_Line ("Enter a number:");
declare
Input : constant String := Get_Line; -- (Ada 2005)
Number : Integer;
begin
exit when Input'Length = 0;
Number := Value (Input);
Put_Line ("You typed " & Image (Number));
exception
when Data_Error =>
Put_Line ("Bad input, possibly more than one number");
when End_Error =>
Put_Line ("No number found");
when Constraint_Error =>
Put_Line ("The number is too large");
end;
end loop;
end Numeric_Input;

jedivaughn

unread,
Mar 31, 2008, 10:44:52 AM3/31/08
to
Ok, Let me start over. Maybe I'm not approaching my problem the right
way. I'm trying to write a program that converts integers to roman
numerals or vice versa depending on the user input. to do this I
thought I would get the input in separate characters so that I can
easily compare the values to find whether the user inputed IX or XI or
something else. This works until unless the user wants to convert an
integer to roman numeral. to change the input to an integer I'm using
this int:=Integer'Value(str); But for this to work the input has to be
in a string not a character. I thought about taking the input as a
string and then doing a string slice on the characters and storing
them in different variables but once again I'm not sure how many
characters will be entered so how can I do that? So how would be the
optimal way of going about this?

Thanks once again for your patience

John

Adam Beneschan

unread,
Mar 31, 2008, 11:41:25 AM3/31/08
to
On Mar 31, 7:44 am, jedivaughn <jedivaugh...@gmail.com> wrote:
> Ok, Let me start over. Maybe I'm not approaching my problem the right
> way. I'm trying to write a program that converts integers to roman
> numerals or vice versa depending on the user input. to do this I
> thought I would get the input in separate characters so that I can
> easily compare the values to find whether the user inputed IX or XI or
> something else.

Perhaps I'm not understanding you correctly, but I don't see why you
need to get the input in separate characters, or why that would be
helpful. You can always get the input as an entire string, using
Ada.Text_IO.Get_Line, and then *process* the input as separate
characters.

I almost never use single-character input. The only time I would want
to is if, for some reason, you need the program to react immediately
to some key that's typed in (other than Return or Enter). E.g. I've
written programs that will do something interesting if the user
presses the up-arrow or down-arrow keys on the keyboard. That was
done using the Get routine. If you don't do anything like that, then
you should use Get_Line. (For one thing, you don't have to worry
about handling the user's backspaces.)

So your code might look something like:

Ada.Text_IO.Get_Line (Input_Str, Last_Index);
for Index in Input_Str'First .. Last_Index loop
... Input_Str(Index) will be the character you're looking
at...
end loop;

or, if you want to examine characters outside the loop:

Ada.Text_IO.Get_Line (Input_Str, Last_Index);
Curr_Index := Input_Str'First;
while Curr_Index <= Last_Index and then Input_Str(Curr_Index) = '
' loop
Curr_Index := Curr_Index + 1;
end loop;
... special handling for case where Curr_Index > Last_Index! The
... user entered an blank string
if Input_Str(Curr_Index) = 'I' or else
Input_Str(Curr_Index) = 'V' ... then
... it's better to use an array of Boolean for this
Do_Something_With_Roman_Numeral (Input_Str
(Input_Str'First ..
Last_Index));
elsif Input_Str(Curr_Index) in '0'..'9' then
Do_Something_With_Integer (Input_Str (Input_Str'First ..
Last_Index));
else
... ??? user error

OK, this is just an example of how you might handle things; I really
am not sure what sort of processing you're trying to do. But my point
is to show that you probably ought to be using Get_Line and not
worrying about how to input one character at a time.

-- Adam

Dmitry A. Kazakov

unread,
Mar 31, 2008, 11:45:21 AM3/31/08
to

Sorry, I still do not understand the problem. You read a line. Then you
skip spaces there. Then you try to parse an integer number starting from
that position. If that fails you try to parse a Roman number. After
successful parsing you advance to the position following the number and
skip spaces again. Then you check if the whole like was matched. That's it.

Here is a complete program:
--------------------------


with Ada.Text_IO; use Ada.Text_IO;
with Strings_Edit.Integers; use Strings_Edit.Integers;

with Strings_Edit.Roman_Edit; use Strings_Edit.Roman_Edit;

procedure Arabic_Roman_Converter is


begin
loop
Put_Line ("Enter a number:");
declare
Input : constant String := Get_Line;

Number : Integer;
begin
exit when Input'Length = 0;

begin
Number := Value (Input);
Put_Line ("You typed " & Image (Roman (Number)));
exception
when End_Error =>
-- OK, no integer here, maybe it is a Roman number?
Number := Integer (Roman'(Value (Input)));


Put_Line ("You typed " & Image (Number));

end;
exception
when Data_Error =>
Put_Line ("Bad input, possibly syntax or several numbers");


when Constraint_Error =>
Put_Line ("The number is too large");

when End_Error =>
Put_Line ("No any number found");
end;
end loop;
end Arabic_Roman_Converter;
-----------------------------------
Enter a number:
II
You typed 2
Enter a number:
3
You typed III
Enter a number:
1000
You typed M
Enter a number:
f
No any number found
Enter a number:

Maciej Sobczak

unread,
Mar 31, 2008, 4:26:36 PM3/31/08
to
On 31 Mar, 17:41, Adam Beneschan <a...@irvine.com> wrote:

> I almost never use single-character input. The only time I would want
> to is if, for some reason, you need the program to react immediately
> to some key that's typed in (other than Return or Enter). E.g. I've
> written programs that will do something interesting if the user
> presses the up-arrow or down-arrow keys on the keyboard.

How did you do this?
Normally, the operating system (the terminal, actually), isolates the
process from all such things and feeds the complete line of text to
the process' input queue *after* it is committed by Enter. The program
has no way to react to individual keystrokes.

Unless you talked to the terminal directly - but then it was not
Ada.Text_IO.

Did I miss something?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Georg Bauhaus

unread,
Mar 31, 2008, 6:06:22 PM3/31/08
to
Maciej Sobczak wrote:
> On 31 Mar, 17:41, Adam Beneschan <a...@irvine.com> wrote:
>
>> I almost never use single-character input. The only time I would want
>> to is if, for some reason, you need the program to react immediately
>> to some key that's typed in (other than Return or Enter). E.g. I've
>> written programs that will do something interesting if the user
>> presses the up-arrow or down-arrow keys on the keyboard.
>
> ... The program

> has no way to react to individual keystrokes.
>
> Unless you talked to the terminal directly - but then it was not
> Ada.Text_IO.

I'd speculate that Ada.Text_IO.Get_Immediate, reading both
control and graphic characters, might have been helpful to
some extent. ;-)

Adam Beneschan

unread,
Mar 31, 2008, 6:33:45 PM3/31/08
to
On Mar 31, 1:26 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> On 31 Mar, 17:41, Adam Beneschan <a...@irvine.com> wrote:
>
> > I almost never use single-character input. The only time I would want
> > to is if, for some reason, you need the program to react immediately
> > to some key that's typed in (other than Return or Enter). E.g. I've
> > written programs that will do something interesting if the user
> > presses the up-arrow or down-arrow keys on the keyboard.
>
> How did you do this?
> Normally, the operating system (the terminal, actually), isolates the
> process from all such things and feeds the complete line of text to
> the process' input queue *after* it is committed by Enter. The program
> has no way to react to individual keystrokes.

No, any decent OS would provide a way to input immediate keystrokes.
On Linux, I think it involves a call to either ioctl() or
tcsetattr()---I don't remember---to turn off the OS's complete-line
handling.

As Georg pointed out, Get_Immediate is available in Ada to do this for
you. Actually, I may have written this program before Ada 95 was
available, which meant that Get_Immediate wasn't available, so
something tricky had to be done. But my program still uses
Text_IO.Get. Of course, whatever I did is non-portable.

Anyway, I'm a bit sorry I mentioned this, because it has nothing to do
with the point I was trying to make.

-- Adam

jedivaughn

unread,
Mar 31, 2008, 9:00:03 PM3/31/08
to
Ok So I've almost solved my problem. my only question now is I need to
convert one character to an integer. I know the input is a integer so
it's not going to give me a constraint error but how will I convert
one character to an integer?

Simon Wright

unread,
Apr 1, 2008, 1:34:17 AM4/1/08
to
jedivaughn <jediva...@gmail.com> writes:

Make a one-character String holding your Character & convert that?

with ada.text_io;
procedure blah is
i : integer := integer'value (string'(1 .. 1 => '7'));
begin
ada.text_io.put_line ("i => " & integer'image (i));
end blah;

jedivaughn

unread,
Apr 1, 2008, 7:22:55 AM4/1/08
to
On Apr 1, 1:34 am, Simon Wright <simon.j.wri...@mac.com> wrote:


not exactly what I was looking for. I have a number stored in a
character. and I want to turn that into a integer. so I can add it to
another integer. So say I have the number '5' stored in a character
and I want that in an integer not a character or string. how would I
do that?

jimmaure...@worldnet.att.net

unread,
Apr 1, 2008, 8:00:49 AM4/1/08
to

Given your stated goal of converting decimal integers into Roman
numerals,
your goal of dealing with one digit at a time will always lead you
astray.

Why not read the entire set of digits as an integer directly?

Given the number 1994, your result should be MCMXCIV.
You cannot arrive at the correct result simply reading one digit at a
time.

Jim Rogers

jedivaughn

unread,
Apr 1, 2008, 9:22:49 AM4/1/08
to
What I'm doing is taking the first character the user enters and
looking at it to determine whether or not it is a integer roman
numeral or the letter Q (for quit). if it's a integer then I need to
convert the single character to a roman numeral and I take the rest of
the input as a string and convert it to an integer using

int := integer'value(char);

so basically I then need to know how to convert the single character I
used to determine whether or not the input was a integer roman numeral
or the letter Q to an integer. And then I can add it to the integer to
find the roman numeral vlaue.

- John

Adam Beneschan

unread,
Apr 1, 2008, 12:58:20 PM4/1/08
to

If C is a character and you know it is in the range '0'..'9':

Character'Pos(C) - Character'Pos('0')

-- Adam

Adam Beneschan

unread,
Apr 1, 2008, 1:03:47 PM4/1/08
to

I think you're really on the wrong track. Assuming you've taken my
advice and are using Get_Line to read an entire string first, you can
look at the first character of the string to see whether it's Q or a
digit. Once you've done this, the input string will still be there in
its entirety, including the first character that you've checked for
'Q'. So why do you need to convert that one digit to an integer? You
can still convert the entire input string using Integer'Value.

Even if for some reason you have to use Get_Immediate to read the
first character, you can store that character in a string, use
Get_Line to read the rest of the string, use one of several methods
(concatenation and slices come to mind) to put the first character
together with the rest of the string, then use Integer'Value to
convert the string as a whole.

Unless I'm misunderstanding the task you're trying to accomplish, I
don't see any reason why you would have to deal with converting a
single character to an integer.

-- Adam

Simon Wright

unread,
Apr 1, 2008, 5:11:26 PM4/1/08
to
jedivaughn <jediva...@gmail.com> writes:

It may not be what you are looking for but it is **exactly** what you
asked for!

If I'd said

function to_integer (c : character) return integer is
begin
return integer'value (string'(1 .. 1 => c));
end to_integer;

would it be clearer?

You could try compiling and running my example, I assure you it works.

jedivaughn

unread,
Apr 1, 2008, 6:22:11 PM4/1/08
to
Thank you to everyone who helped me acomplish my goal. I finally got
it done. Thank you Adam for the suggestion. in the end I did what you
said and it worked! Thank you again everyone.

- John

tmo...@acm.org

unread,
Apr 3, 2008, 1:54:01 AM4/3/08
to
>So say I have the number '5' stored in a character
>and I want that in an integer not a character or string. how would I
>do that?

Value : constant array(Character range '0' .. '9') := (0,1,2,3,4,5,6,7,8,9);
...
X := Value(C);

Adam Beneschan

unread,
Apr 3, 2008, 10:38:57 AM4/3/08
to
On Apr 2, 10:54 pm, tmo...@acm.org wrote:
> >So say I have the number '5' stored in a character
> >and I want that in an integer not a character or string. how would I
> >do that?

We don't have untyped Ada, yet. So array elements have to have types:

> Value : constant array(Character range '0' .. '9')

of integer

> := (0,1,2,3,4,5,6,7,8,9);
> ...
> X := Value(C);

-- Adam

0 new messages