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
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
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
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
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.
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
Thanks for your patience
John
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.
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.
> 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
> 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
Thanks,
- John
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.
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;
Thanks once again for your patience
John
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
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:
> 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
I'd speculate that Ada.Text_IO.Get_Immediate, reading both
control and graphic characters, might have been helpful to
some extent. ;-)
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
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;
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?
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
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
If C is a character and you know it is in the range '0'..'9':
Character'Pos(C) - Character'Pos('0')
-- Adam
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
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.
- John
Value : constant array(Character range '0' .. '9') := (0,1,2,3,4,5,6,7,8,9);
...
X := Value(C);
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