Something like "Is a number"?

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

Something like "Is a number"?

Thomas Zastrow
Hello,

I'm converting some strings with "strtoint" into integers. But sometimes
the string can't be converted to a number. Is there a function which
takes a string and tells me if it is possible or not to convert it into
a number? Something like "IsANumber(string)"

Thank you very much!

Greetings,

Tom


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Something like "Is a number"?

John Coppens
On Fri, 08 Jul 2005 16:39:05 +0200
Thomas Zastrow <[hidden email]> wrote:

> Hello,
>
> I'm converting some strings with "strtoint" into integers. But
> sometimes the string can't be converted to a number. Is there a
> function which takes a string and tells me if it is possible or not to
> convert it into a number? Something like "IsANumber(string)"
>
You can use val(str, int/real, err)

if err is 0, the string was converted to an integer or real (depending on
the type of int/real.

John

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Something like "Is a number"?

Thomas Zastrow
John Coppens wrote:

>On Fri, 08 Jul 2005 16:39:05 +0200
>Thomas Zastrow <[hidden email]> wrote:
>
>  
>
>>Hello,
>>
>>I'm converting some strings with "strtoint" into integers. But
>>sometimes the string can't be converted to a number. Is there a
>>function which takes a string and tells me if it is possible or not to
>>convert it into a number? Something like "IsANumber(string)"
>>
>>    
>>
>You can use val(str, int/real, err)
>
>if err is 0, the string was converted to an integer or real (depending on
>the type of int/real.
>
>John
>  
>
Thank you, it's working!!!

Greetings,

Tom


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Something like "Is a number"?

Florian Klaempfl-2
Thomas Zastrow wrote:

> John Coppens wrote:
>
>> On Fri, 08 Jul 2005 16:39:05 +0200
>> Thomas Zastrow <[hidden email]> wrote:
>>
>>  
>>
>>> Hello,
>>>
>>> I'm converting some strings with "strtoint" into integers. But
>>> sometimes the string can't be converted to a number. Is there a
>>> function which takes a string and tells me if it is possible or not to
>>> convert it into a number? Something like "IsANumber(string)"
>>>
>>>  
>>
>> You can use val(str, int/real, err)
>>
>> if err is 0, the string was converted to an integer or real (depending on
>> the type of int/real.
>>
>> John
>>  
>>
> Thank you, it's working!!!

You can also use TryStrToInt from the sysutils unit.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Something like "Is a number"?

A.J. Venter
In reply to this post by Thomas Zastrow

> >You can use val(str, int/real, err)
> >
> >if err is 0, the string was converted to an integer or real (depending on
> >the type of int/real.
> >
> >John
>
> Thank you, it's working!!!
>
Yes that's the old Pascal version of StrToInt :) and it had errorchecking :)
Just for the record, like everything it has more than one answer, you could
also have done:
try
 Int := strToInt(Str);
except
 Int := -1 {Or whatever error number}
end;

Or if you wanted to prepend exceptions rather than catch them, the following
function could also work have worked (note you have to do a shortString cast,
AnsiStrings don't like access by character)

Function IsANumber (InStr : String) : Boolean
Var TempBool : Boolean;
      Str : ShortString;
      I : Integer;
Begin
Str := ShortString(InStr);
TempBool := True;
I := 1;

While (I <= Length(Str)) and (TempBool = True) do
Begin
 TempBool := Str[I] in ['0'..'9'];
 Inc(I);
end;

IsANumber := TempBool
end;

Of course, that's a rather ugly way to do it, I don't suggest it in practice
except for very special cases but I put it here to give an idea of the ways
you can interact between types. One of Pascal's (and by inheritance object
pascal's) greatest features is that it is not only strongly typed but has
very strict type checking, which prevents a very large number of the problems
C coders face. For starters you don't have to take measures against about a
potential buffer overflow every time you use strings, it does mean though
that getting data from one type to another is sometimes a little harder than
a simple cast (like in say java), but if you understand the ways in which
data types are actually implemented and how they relate to each other you can
do not only everything you can do in untyped or weakly-typed languages but a
great deal more.

Ciao
A.J.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Something like "Is a number"?

Nico Aragón
In reply to this post by John Coppens
El Viernes, 8 de Julio de 2005 19:39, John Coppens escribió:
>
> You can use val(str, int/real, err)

If I remeber correctly, the point is hardcoded in Val as decimal separator. A
problem for countries in which we use different conventions.

--
saludos,

    Nico Aragón

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

ansistrings access by character

L505
In reply to this post by A.J. Venter
|
| Or if you wanted to prepend exceptions rather than catch them, the following
| function could also work have worked (note you have to do a shortString cast,
| AnsiStrings don't like access by character)
|

I was under the same impression for a long time, but some of the FPC RTL sources
use ansistrings and access by character. The findpart function for example uses
ansistrings but accesses by string[n]


For example this compiles and runs.

var
 test:ansistring;
function IsANumber (InStr : AnsiString) : Boolean;
var
  TempBool: Boolean;
  Str: ansiString;
  I: Integer;
begin
 Str := InStr;
 TempBool := True;
 I := 1;

 while (I <= Length(Str)) and (TempBool = True) do
 begin
  TempBool := Str[I] in ['0'..'9'];
  Inc(I);
 end;
 IsANumber := TempBool
end;

begin
 test:='testing';
 test[1]:='p';
 writeln(test);

 test:='5453tyy';
 if IsANumber(test) then
   writeln('yes '+test+' is a number')
 else
   writeln('no, '+test+' is not a number');

 test:='545365';
 if IsANumber(test) then
   writeln('yes '+test+' is a number')
 else
   writeln('no, '+test+' is not a number');

 readln;

end.


So can someone shed the light? Is it just a rumor that ansistrings shouldn't be
accessed by character? Only specific situations?


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

function returning a record vs paramaters

L505
When a function requires that more than one value must be returned, what are the
advantages of returning one of these values in a paramater versus using a record
that contains all the data?

Example:
A function needs to return an integer, string, and boolean.  Why not just return
a record containing an integer, string, and boolean?


Advantages of records:
 Surely records are much more legible code design than parameters.

Disadvantages of records:
 ???
 Are paramaters more portable than records, say if you were writing a library
(.so or .dll, etc.)?
 Can a c++ or c program deal with a pascal record?
 How about speed and performance?


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: function returning a record vs paramaters

Anton Tichawa
L505 wrote:

>When a function requires that more than one value must be returned, what are the
>advantages of returning one of these values in a paramater versus using a record
>that contains all the data?
>
>Example:
>A function needs to return an integer, string, and boolean.  Why not just return
>a record containing an integer, string, and boolean?
>
>  
>
When the integer, string, and boolean are logically related, and are
typically assigned, copied, allocated, stored or else processed as a
whole block, a record should be used anyway.

>Advantages of records:
> Surely records are much more legible code design than parameters.
>
>  
>
Yes, especially in function calls, as in your example.

>Disadvantages of records:
> ???
> Are paramaters more portable than records, say if you were writing a library
>(.so or .dll, etc.)?
> Can a c++ or c program deal with a pascal record?
> How about speed and performance?
>
>  
>
I think the best way is to pass the record as a var parameter, e. g.:

type t_my_record = record
  a: integer;
  b: string;
  c: boolean;
end;

procedure my_procedure(var a_record: t_my_record);

In this case, a simple pointer is passed to my_procedure. This is also
the way most C libraries work, passing a pointer to a structure.

When a function returns a record, an additional pointer parameter is
passed to it, invisibly to the pascal programmer, and the function fills
in the structure pointed to by that parameter.

For this reason, I personally tend to prefer a var-parameter: A function
returning a record looks like creating or allocating that record, which
is not true. A  var-parameter shows, in pascal, a structure similar to
what happens on the machine code level. But it's a matter of taste, and,
of how the function result is used: When the result is often used as
part of expressions, or as a parameter to other procedures, the "result"
way is more legible than the "var-parameter" way.

Anton.



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: function returning a record vs paramaters

L505
In reply to this post by L505

| possible to improve.. but I'm not so sure if it can. It's real high priority
| though, since most people know you can return a value as a parameter.


Not real high priority, is what I meant to say.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: function returning a record vs paramaters

L505
In reply to this post by Anton Tichawa

| procedure my_procedure(var a_record: t_my_record);
|
| In this case, a simple pointer is passed to my_procedure. This is also
| the way most C libraries work, passing a pointer to a structure.

Would a C program be able to call a Pascal SO or DLL file and directly read a
record from pascal, as a structure in C? i.e. no hassles required (presuming the
record didn't contain strings of course.. let's just say three integers)


|
| When a function returns a record, an additional pointer parameter is
| passed to it, invisibly to the pascal programmer, and the function fills
| in the structure pointed to by that parameter.

some performance loss then. But not actually twice the memory used to make a
copy?

|
| For this reason, I personally tend to prefer a var-parameter: A function
| returning a record looks like creating or allocating that record, which
| is not true. A  var-parameter shows, in pascal, a structure similar to
| what happens on the machine code level. But it's a matter of taste, and,
| of how the function result is used: When the result is often used as
| part of expressions, or as a parameter to other procedures, the "result"
| way is more legible than the "var-parameter" way.

Maybe make it easier, a result prefix or something like so could be used:

procedure(integer, string, other, Result_Record);

or

function(integer, string, other, Result_Record): boolean;

or

function(integer, string, other, ResultRecord): boolean;

Researching this topic, I found some arguments and discussions from people using
other languages coming across the same questions - such as Ada people
questioning the Out keyword in their functions, and so on. I just want to
clarify what the best way is.. I do like returning a record since the code
appears more clear to me this way, but I suppose I'll use a parameter for
performance reasons.

When teaching people Pascal or learning Pascal, I'm sure people will question
how a parameter can possibly return a variable.. "isn't that what the result is
supposed to do?" So it does feel sort of hackish to do that. It feels very
win32api-ish too. In this case, I wish there were a way to make code clearer
while still offering the same performance/benefits. I think Result_Record is
somewhat of a hack too.. almost like a "workaround" to something that might be
possible to improve.. but I'm not so sure if it can. It's real high priority
though, since most people know you can return a value as a parameter.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: function returning a record vs paramaters

Anton Tichawa
L505 wrote:

>| procedure my_procedure(var a_record: t_my_record);
>|
>| In this case, a simple pointer is passed to my_procedure. This is also
>| the way most C libraries work, passing a pointer to a structure.
>
>Would a C program be able to call a Pascal SO or DLL file and directly read a
>record from pascal, as a structure in C? i.e. no hassles required (presuming the
>record didn't contain strings of course.. let's just say three integers)
>
>  
>
Yes. Hassles are still there:

1. The pascal record and the C structure have to allocate and pack data
the same way, with the same data sizes and semantics (you mentioned
strings, but also "int" and "integer" change their size every few years,
bool / BOOL / boolean have different semantics, ...)

2. Calling conventions have to match. They can be set using procedure
modifiers like "stdcall", "cdecl" etc. You have to check the docs here.

>|
>| When a function returns a record, an additional pointer parameter is
>| passed to it, invisibly to the pascal programmer, and the function fills
>| in the structure pointed to by that parameter.
>
>some performance loss then. But not actually twice the memory used to make a
>copy?
>
>  
>
No. Even no performance loss. The "additional pointer" is the same as
the otherwise used "var parameter". The following two pascal procedure
do essentially the same, they just differ in syntax:

function proc_1: t_record;
begin
  result.a := 1;
end;

procedure proc_2(var x: t_record);
begin
  x.a := 1;
end;

The first form, proc_1, is silently converted to the second form, by the
compiler.

>|
>| For this reason, I personally tend to prefer a var-parameter: A function
>| returning a record looks like creating or allocating that record, which
>| is not true. A  var-parameter shows, in pascal, a structure similar to
>| what happens on the machine code level. But it's a matter of taste, and,
>| of how the function result is used: When the result is often used as
>| part of expressions, or as a parameter to other procedures, the "result"
>| way is more legible than the "var-parameter" way.
>
>Maybe make it easier, a result prefix or something like so could be used:
>
>procedure(integer, string, other, Result_Record);
>
>or
>
>function(integer, string, other, Result_Record): boolean;
>
>or
>
>function(integer, string, other, ResultRecord): boolean;
>
>Researching this topic, I found some arguments and discussions from people using
>other languages coming across the same questions - such as Ada people
>questioning the Out keyword in their functions, and so on. I just want to
>clarify what the best way is.. I do like returning a record since the code
>appears more clear to me this way, but I suppose I'll use a parameter for
>performance reasons.
>
>  
>
At least for free pascal, there is no lack in performance when you
"return a record".

>When teaching people Pascal or learning Pascal, I'm sure people will question
>how a parameter can possibly return a variable.. "isn't that what the result is
>supposed to do?" So it does feel sort of hackish to do that. It feels very
>win32api-ish too. In this case, I wish there were a way to make code clearer
>while still offering the same performance/benefits. I think Result_Record is
>somewhat of a hack too.. almost like a "workaround" to something that might be
>possible to improve.. but I'm not so sure if it can. It's real high priority
>though, since most people know you can return a value as a parameter.
>
>  
>
I'm not sure if I get your point right, especially concerning Ada ...
Anyway, if people question how a parameter can possibly return a value,
tell them a "var parameter" allows more than a function result. It
allows the called procedure to -act- on the data, including both reading
and writing. That would be "in out" in Ada. In Pascal, this is also
known as "call by reference", and not necessarily hackish ... Think of a
procedure that calculates and inserts the checksum in a telegram that
already contains valid data:

procedure insert_checksum(var a_telegram: t_telegram_record);

This procedure reads the telegram data, calculates some sort of checksum
and fills in the telegram's checksum field. This cannot be done with the
"return a record" method, except when passing the parameter twice (=
performance loss).

But, if you just have to return data, without reading it's previous
contents, you may use the "return a record" method without performance loss.

Anton.



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: function returning a record vs paramaters

L505
| No. Even no performance loss. The "additional pointer" is the same as
| the otherwise used "var parameter". The following two pascal procedure
| do essentially the same, they just differ in syntax:
|
| function proc_1: t_record;
| begin
|   result.a := 1;
| end;
|
| procedure proc_2(var x: t_record);
| begin
|   x.a := 1;
| end;
|
| The first form, proc_1, is silently converted to the second form, by the
| compiler.

Thanks for clearing up that.  Same amount of pointers in the end.


| At least for free pascal, there is no lack in performance when you
| "return a record".
|
| I'm not sure if I get your point right, especially concerning Ada ...
| Anyway, if people question how a parameter can possibly return a value,
| tell them a "var parameter" allows more than a function result. It
| allows the called procedure to -act- on the data, including both reading

Yes, and useful in recursive situations.. because you don't want to be
re-copying the data to another var if it's just going to be re-used again and
again anyway. Might as well just add on or modify the existing var over and over
again.

| and writing. That would be "in out" in Ada. In Pascal, this is also
| known as "call by reference", and not necessarily hackish ... Think of a
| procedure that calculates and inserts the checksum in a telegram that
| already contains valid data:

Well, confusing especially when you are using code completion/code insight - the
vars inside brackets get confusing. You can't tell which vars inside the
brackets are result parameters(dummy ones), and which are your working
parameters. Unless they were prefixed with Result_ , or unless you really knew
the function well (more time in the help docs).

If the variable is prefixed with result_ for example, you at least know while
looking at code insight, that this is a result variable, (a dummy variable). It
stops you from going into the help docs, or getting confused as much.

The other issue is that people are afraid of global variables or even partially
global variables, and all sorts of people say to not use them.. but obviously
they are very useful in some situations.

|
| procedure insert_checksum(var a_telegram: t_telegram_record);
|
| This procedure reads the telegram data, calculates some sort of checksum
| and fills in the telegram's checksum field. This cannot be done with the
| "return a record" method, except when passing the parameter twice (=
| performance loss).

Right, so definitely use the right tool for the right job. I've done this a few
times where it makes sense to use the existing var to modify existing data. I
just have failed to acknowledge those situations it seems (hehe).

One could go as far as never even using functions at all, and just using
procedures. But definitely more readable if you utilize them in the right
situations. I think for code insight and clarity purposes I'll stick to
returning data as value where possible. But like you say, when modifying
existing data, utilize the "passing a parameter" or "call by reference" way It
will be more effiecient and offers less code noise and var copying.





_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Sage Api : Pinging Jason

L505
Anyone know what Jason Sage's current working email address is? His Hotmail
appears to be down. I wanted to check the sage API and his files. If he doesn't'
have FTP access I can upload his files to z505 ftp.

Also, if anyone else has files that have gone dead, let me know, send, and I'll
put em up.

Regards.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: ansistrings access by character

Florian Klaempfl-2
In reply to this post by L505
L505 wrote:

> |
> | Or if you wanted to prepend exceptions rather than catch them, the following
> | function could also work have worked (note you have to do a shortString cast,
> | AnsiStrings don't like access by character)
> |
>
> I was under the same impression for a long time, but some of the FPC RTL sources
> use ansistrings and access by character. The findpart function for example uses
> ansistrings but accesses by string[n]
>
>
> For example this compiles and runs.
>
> var
>  test:ansistring;
> function IsANumber (InStr : AnsiString) : Boolean;
> var
>   TempBool: Boolean;
>   Str: ansiString;
>   I: Integer;
> begin
>  Str := InStr;
>  TempBool := True;
>  I := 1;
>
>  while (I <= Length(Str)) and (TempBool = True) do
>  begin
>   TempBool := Str[I] in ['0'..'9'];
>   Inc(I);
>  end;
>  IsANumber := TempBool
> end;
>
> begin
>  test:='testing';
>  test[1]:='p';
>  writeln(test);
>
>  test:='5453tyy';
>  if IsANumber(test) then
>    writeln('yes '+test+' is a number')
>  else
>    writeln('no, '+test+' is not a number');
>
>  test:='545365';
>  if IsANumber(test) then
>    writeln('yes '+test+' is a number')
>  else
>    writeln('no, '+test+' is not a number');
>
>  readln;
>
> end.
>
>
> So can someone shed the light? Is it just a rumor that ansistrings shouldn't be
> accessed by character? Only specific situations?

Disadvantage:
- it's slow because it calls unique,i.e. ensures that the reference
counter is 1


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: function returning a record vs paramaters

Marco van de Voort
In reply to this post by L505
> | procedure my_procedure(var a_record: t_my_record);
> |
> | In this case, a simple pointer is passed to my_procedure. This is also
> | the way most C libraries work, passing a pointer to a structure.
>
> Would a C program be able to call a Pascal SO or DLL file and directly read a
> record from pascal, as a structure in C? i.e. no hassles required (presuming the
> record didn't contain strings of course.. let's just say three integers)

Portability is more between specific compilers than between languages.

If the C compiler can be configured to match whatever recordlayout the Pascal
compiler is using, then it works.

P.s. I'd recommend against using complex types as a parameter result. It is
unoptimal. Unless there is a very good reason to pair them into a record,
I'd simply use multiple var parameters, and use the return value for the success
or failure indicator of the function.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal