Avatar billede tt2002 Nybegynder
22. juli 2004 - 22:58 Der er 24 kommentarer og
1 løsning

Prøve at konvertere string til int eller curr

Kan man på en eller anden måde undersøge om en string kan konverteres til integer eller currency(real) inden man rent faktisk gør det? Jeg vil gerne undgå fejlkommandoen når man konverterer en string som indeholder andet end tal.
Avatar billede arne_v Ekspert
22. juli 2004 - 23:07 #1
function isnumber(s : string) : boolean;

var
  i: integer;

begin
  result := true;
  for i := 1 to length(s) do
    if not (s[i] in ['0'..'9']) then
    begin
      result := false;
      exit;
    end;
end;
Avatar billede tt2002 Nybegynder
22. juli 2004 - 23:09 #2
tror ikke det vil virke...
vil reagere forkert på kommatal (eks. "345,67")
Avatar billede arne_v Ekspert
22. juli 2004 - 23:11 #3
Så tilføjer du komma til settet:

function isnumber2(s : string) : boolean;

var
  i: integer;

begin
  result := true;
  for i := 1 to length(s) do
    if not (s[i] in ['0'..'9',',']) then
    begin
      result := false;
      exit;
    end;
end;
Avatar billede arne_v Ekspert
22. juli 2004 - 23:14 #4
Den fanger ikke situationer med 2 kommaer, men ...
Avatar billede tt2002 Nybegynder
22. juli 2004 - 23:16 #5
så duer det nok ikke rigtigt
Avatar billede arne_v Ekspert
22. juli 2004 - 23:20 #6
function isnumber2(s : string) : boolean;

var
  e : integer;
  x : real;

begin
  val(s, x, e);
  Result := (e = 0);
end;
Avatar billede arne_v Ekspert
22. juli 2004 - 23:21 #7
Den konverterer faktisk men smider ingen fejl.

Og den skulle derfro håndtere alle mulige special tilfælde.
Avatar billede tt2002 Nybegynder
22. juli 2004 - 23:25 #8
jeg forstår ikke hvordan den skulle virke...
kan heller ikke se at den gør...
Avatar billede arne_v Ekspert
22. juli 2004 - 23:27 #9
Det gør den.

Fra docs til Val:

Code is a variable of type Integer.

If the string is invalid, the index of the offending character is stored in Code; otherwise, Code is set to zero.
Avatar billede arne_v Ekspert
22. juli 2004 - 23:29 #10
writeln(isnumber2('123'));
  writeln(isnumber2('123,456'));
  writeln(isnumber2('123,456,789'));
  writeln(isnumber2('123.456'));
  writeln(isnumber2('123.456.789'));
  writeln(isnumber2('abc'));

giver

TRUE
FALSE
FALSE
TRUE
FALSE
FALSE

hvilket er korrekt (med engelsk opsætning).
Avatar billede tt2002 Nybegynder
22. juli 2004 - 23:33 #11
ok
jeg kigger på det og vender tilbage
Avatar billede borrisholt Novice
23. juli 2004 - 08:23 #12
I Delphi har borland glemt at lave en sådan funktion derfor er du nød til at skrive dem selv. Jeg bruger det følgende, som implementerings og interface messigt ligger sig op af Borlands kode :

function TryStrToCurr(S: string; var Value: Currency): Boolean;
begin
  s := StringReplace(S, ThousandSeparator, '', [rfReplaceAll]);
  if s = '' then
    Result := False
  else
    Result := TextToFloat(Pointer(S), Value, fvCurrency);
end;

function TryStrToFloat(S: string; var Value: Extended): Boolean;
begin
  s := StringReplace(S, ThousandSeparator, '', [rfReplaceAll]);
  if s = '' then
    Result := False
  else
    Result := TextToFloat(Pointer(S), Value, fvExtended);
end;

function StrToCurrDef(const Str: string; Default: Currency): Currency;
var
  Curr: Currency;
begin
  if not TryStrToCurr(Str, Curr) then
    Result := Default
  else
    Result := Curr;
end;

function StrToFloatDef(const Str: string; Default: Extended): Extended;
var
  Value: Extended;
begin
  if not TryStrToFloat(Str, Value) then
    Result := Default
  else
    Result := Value;
end;


function JBStrToCurrDef(S: string; const Default: Currency): Currency;
var
  i: Integer;
begin
  I := 1;
  while I <= Length(S) do
  begin
    if not (s[i] in ['0'..'9', DecimalSeparator,'-']) then
      Delete(s, i, 1)
    else
      Inc(i);
  end;

  if not Sysutils.TryStrToCurr(S, Result, FormatSettings) then
    Result := Default;
end;

function JBStrToCurr(const S: string): Currency;
{ Same as StrToCurr, but fault tolerence for ThousandSeparator etc.
  Præ: -
  Post: S converted to a Currency, else 0 (Zero) returned}
begin
  Result := AKStrToCurrDef(s, 0);
end;


Jens B
Avatar billede borrisholt Novice
23. juli 2004 - 08:25 #13
Ovenstående svar gælder kun for Currency.

Med integer og Extended kan du bruge hhv
TryStrtoInt og TryStrToFloat

Jens B
Avatar billede martinlind Nybegynder
23. juli 2004 - 08:57 #14
Hej Jens, har du fået Job i Tåstrup
Avatar billede borrisholt Novice
23. juli 2004 - 09:32 #15
Hej Martin.

Nej det har jeg ikke. Jeg søgte men det var SLET ikke noget. Firmaet var et to mands firma, og de søgte i den sidste ende en WEB programmør ikke en Delphi programmør.

Jeg arbejder stadig i Brøndby hos Techotel.

Jens B
Avatar billede tt2002 Nybegynder
23. juli 2004 - 22:55 #16
arne v.
kan stadig ikke finde en sammenhæng
Avatar billede arne_v Ekspert
23. juli 2004 - 22:58 #17
Funktionen kalder Val funktionen, hvis det er et tal så sætter den e til nul.

Derfor hvis e er nul så er det et tal ellers ikke.
Avatar billede tt2002 Nybegynder
23. juli 2004 - 22:58 #18
borrisholt.
virker meget godt, men der er tre ting:
- "if not Sysutils.TryStrToCurr(S, Result, FormatSettings) then", hvad er FormatSettings, delphi kan ikke forstå det.
- "Result := AKStrToCurrDef(s, 0);", hvad betyder AKStrToCurrDef?
- VIGTIGST AF ALT: hvordan indfletter jeg det til rent faktisk brug?
Avatar billede tt2002 Nybegynder
23. juli 2004 - 23:08 #19
arne v.
okay så forstår jeg...
men hvordan bruger jeg det, hvis jeg f.eks. skal tjekke om Edit.Text er et tal eller ej?
Avatar billede arne_v Ekspert
23. juli 2004 - 23:09 #20
if isnumber2(Edit.Text) then begin
...
end
Avatar billede tt2002 Nybegynder
23. juli 2004 - 23:11 #21
okay.
men det virker tilsyneladende kun med integer
Avatar billede arne_v Ekspert
23. juli 2004 - 23:13 #22
Bruger du komma eller punktum til decimal tal ?

Kører du DK eller UK sprog ?
Avatar billede tt2002 Nybegynder
23. juli 2004 - 23:16 #23
kører DK sprog i windows, men UK i Delphi...

hvis jeg bruger komma genkender funktionen den ikke som et tal
bruger jeg punktum genkender den det som et tal

men det skulle gerne være omvendt...
Avatar billede arne_v Ekspert
23. juli 2004 - 23:19 #24
Så brug den her variant:

function isnumber3(s : string) : boolean;

var
  s2 : string;
  e : integer;
  x : real;

begin
  s2 := stringreplace(s,'.','X',[rfReplaceAll]);
  s2 := stringreplace(s2,',','.',[rfReplaceAll]);
  val(s2, x, e);
  Result := (e = 0);
end;
Avatar billede tt2002 Nybegynder
23. juli 2004 - 23:21 #25
det ser ud til at virke... tak
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester