Konwersja string na double.

0

Witam serdecznie,
szukam sposobu, który z liczby zapisanej jako string w formie '00000000wartość' pozwoli mi wyłuskać samą 'wartośc' pozbywając się zer. W takim formacie dostaję dane pomiarowe, które muszę dalej obrabiać. Przy próbie konwersji strtofloat() generowany jest błąd EConvertError. Nie potrafię zrozumieć skąd on się bierze.

Będę wdzięczny za pomoc
Pozdrawiam
Radek

1

może daj przykład jednej takiej ale PRAWDZIWEJ wartości a nie jakieś twoje widzimisię bo podejrzewam, że problem jest z separatorem dziesiętnym a nie zerami z przodu

0

Iterujesz po liczbach wykonujac dzialanie LICZBA * 10 ^ RZAD, gdzie rzad do cyfra, miejsce wystapienia. Nastepnie wszystko sumujesz.

0
petla np. for i := 1 to length(liczba) do

if liczba[i] <> 0 then
begin
  wartoscint := StrToInt(Copy(wyraz, i, maxint));
  Break;
end;

to jest pseudokod.

0

Kolego danny112,
jeżeli dobrze zrozumiałem twoją propozycję...Jeżeli wrzucę do tablicy string: "0000001010" wynikiem twojego kodu będzie liczba '11' a nie '1010'. Dobrze myślę?

0
rybar napisał(a)

szukam sposobu, który z liczby zapisanej jako string w formie '00000000wartość' pozwoli mi wyłuskać samą 'wartośc' pozbywając się zer.

Czyli masz ciąg znaków, w którym wystarczy wyszukać jakikolwiek inny znak niż 0; Jeśli z reguły zer jest więcej niż innych cyfr - można wyszukiwać od tyłu - przy ogromnej ilość takich wyszukań trochę czasu się zyska (przy mniejszej ilości prawie nic), tylko wtedy należy szukać znaku 0 i jeśli zostanie znaleziony to kopiowanie części łańcucha trzeba rozpocząć od zwiększonego o jeden indeksu;

Do wyłuskania tych danych wystarczy prosta pętla + funkcja Copy:

function RemoveZeros(const ALine: AnsiString): AnsiString;
var
  I: Byte;
begin
  Result := '';

  for I := Length(ALine) downto 1 do
    if ALine[I] = '0' then
    begin
      Result := Copy(ALine, Succ(I), Length(ALine) - I);
      Exit;
    end;
end;
</del> **Objaśnienie w poście poniżej** - przepraszam za zamieszanie...

Jeżeli potrzebujesz zwrócić już skonwertowany ciąg na liczbę - w pętli po znalezieniu znaku 0 należy skorzystać z funkcji konwertującej, np.: StrToInt;

Wątek przenoszę do działu dla początkujących, ponieważ dotyczy podstaw programowania;

1
rybar napisał(a)

W moim przypadku zawsze będzie ciąg znaków, tzn. dla wartości=0 będzie '0000000000'. Co się wtedy stanie?

Jeśli ciąg będzie się składał z samych zer to pętla się nie wykona; Pętlę należy ustawić tak, by licznik był inkrementowany (teraz jest dekrementowany):

function RemoveZeros(const ALine: AnsiString): AnsiString;
var
  I: Byte;
begin
  Result := '0';

  for I := 1 to Length(ALine) do
    if ALine[I] <> '0' then
    begin
      Result := Copy(ALine, I, Length(Aline) - Pred(I));
      Exit;
    end;
end;
rybar napisał(a)

Nie powinno być: 'I := Length(ALine) downto 2 do'??

Nie, bo zostanie pominięty pierwszy znak w łańcuchu; Poprzednia podana przeze mnie funkcja była zła - szukała od tyłu i po napotkaniu pierwszego zera kopiowała część i kończyła; Bezpieczniej jest szukać od pierwszego znaku, bo żadna cyfra nie zostanie stracona w przypadku, gdy ciągiem będzie np.: 0000340054; Powyższy algorytm zwróci 340054, a ten w moim wcześniejszym poście zwróci 54, co jest błędem - za zamieszanie przepraszam - nie wiem gdzie ja miałem głowę...

rybar napisał(a)

Panowie, od wczoraj kombinuję a kod usuwa mi tylko piersze zero

Widać słabo kombinujesz, skoro tyle czasu nie znalazłeś rozwiązania...

1
rybar napisał(a):

Przy próbie konwersji strtofloat() generowany jest błąd EConvertError.

Błąd? Nie ma takiej możliwości.

var r:Double;
  r:=StrToFloat('0000005879');

Proponuję też zainteresować się procedurą Val.

0

Panowie, obydwaj mi pomogliście ale niestety 'zielonego ptaszka' mogę dać tylko jednego. Co do problemu, pobcinałem, pokopiowałem i działa. Wiem, że może dla Was jest to banalne ale ja kupę czasu przy tym straciłem. Niestety droga do nobla jest "długa i ciernista" ale można się wiele nauczyć. Teraz walczę z rysowaniem wykresu w czasie.

0

To, co pobierasz z kontrolera musi zawierać dodatkowe znaki oprócz cyfr i dlatego funkcja StrToFloat zwracała błąd. Zera na początku na pewno nie powodują takiego błędu.
Kontroler zapewne zwraca liczbę całkowitą zatem do konwersji wystarczy użyć StrToInt.
Tych dodatkowych znaków spróbuj się pozbyć za pomocą funkcji Trim

liczba_int:=StrToInt(Trim(liczba_str));

A jeżeli to nie pomoże to "ręcznie" wywalić te znaki.

  while i<Length(liczba_str) do if liczba_str[i] in ['0'..'9'] then Continue else Delete(liczba_str,i,1);

@krwq
Może to ukoi twoje serce :)

var
  liczba_str,tmp:string;
  i,j,n:Integer;
  c:Char;
//
  n:=Length(liczba_str);
  SetLength(tmp,n);
  j:=0;
  for i:=1 to n do
  begin  
    c:=liczba_str[i];
    if c in ['0'..'9'] then
    begin
      Inc(j);
      tmp[j]:=c;
    end;
  end;
  liczba_str:=tmp;
  SetLength(liczba_str,j);
  

1 użytkowników online, w tym zalogowanych: 0, gości: 1