Konvertowanie AnsiString do float w C++ Builder

0

(Sorry mod za tamtą nazwę tematu, w śpiechu jestem z tym)
Mam pewien problem: Robie program do obliczania calego zadania matematycznego na raz (tnz. calej liniejki takiej jak 2+2*5), mam kod pod paskalką konsolę (jeszce w tamtym roku napisałem) i mam go przeprowadzic na c++. Przeprowadzam, gdzie nie gdzie dopisuje parę komand i nie działa. Piszę w Builderze. Próbowałem załadować pasklaski kod w Delphi to mi nie dał zkompilować (? :-/ ? a TP dał). Nie wiem w czym problem, może poradzicie jakiś inny kompilator? oto kody sła w litewskim jez.:

Program Kalkuliatorius;
 uses crt;
 type pilnskch = array [1..100] of real;

 var tekstas:string;
     atsakymas:real;
     klaida,klaida2:boolean;

     Label 2,21;

 const
  skaic: set of char = ['0'..'9'];
  skchk: set of char = ['0'..'9','.'];
  prmsk: set of char = ['0'..'9','(','+','-'];
  zenkl: set of char = ['+','-','*','/'];
  visiz: set of char = ['0'..'9','(',')','+','-','*','/','.'];

procedure showerror(var e:integer); {pokazuje bload}
 var j:integer;
 begin
  for j:=1 to e-1 do write(' ');
  writeln('^');
  writeln(' Cia yra padaryta klaida! Prashom bandyt is naujo ');
  klaida:=true;
  sound(400);
  delay(500);
  nosound;
  end;

Procedure chkkab(var k1:integer; S1:string); {sprawdza nawiasy}
Var k:integer;
    kab2:boolean;
    label 0;
 Begin
  if klaida2=true then goto 0;
  begin
   for k:=k1+1 to length(S1) do
   begin
    if S1[k]='(' then chkkab(k,S1);
    if S1[k]=')' then
     begin
      klaida2:=false;
      goto 0;
     end;
   end;
  end;
 klaida2:=true;
0:End;

Procedure chkkab2(var k2:integer; S2:string); {sprawdza nawiasy odwrotnie}
Var k:integer;
    kab1:boolean;
    label 1;
 Begin
  if klaida=true then goto 1;
  begin
  for k:=k2-1 downto 1 do
   begin
    if S2[k]=')' then chkkab2(k,S2);
    if S2[k]='(' then goto 1;
   end;
  end;
  klaida:=true;
1:End;

Procedure tikrinimas(var S:string); {procedura na sprawdzenie bledow}
 Var i,ii:integer;
 Begin
 klaida:=false;
 klaida2:=false;
  for i:=1 to length(s) do
   begin
   if klaida=false then
   if klaida2=false then
   begin
   ii:=i+1;
    if not (S[i] in visiz) then klaida:=true;
    if not (S[1] in prmsk) then klaida:=true;
   if S[i]='.' then
    if not(S[i-1] in skaic) then klaida:=true else
    if not(s[i+1] in skaic) then klaida:=true;
   if S[i] in skaic then
    if S[ii]='(' then klaida2:=true else
    if S[ii]=' ' then klaida2:=true;
    if S[i]='('then
     if not(S[ii] in prmsk) then klaida2:=true;
   if S[i]=')' then
    if S[ii] in skaic then klaida2:=true else
    if S[ii]=' ' then  klaida2:=true else
    if S[ii]='(' then klaida2:=true;
   if S[i] in zenkl then
    if S[ii]=' ' then klaida2:=true else
    if S[ii]=')' then klaida2:=true else
    if s[ii] in zenkl then klaida2:=true;
    if klaida=true then showerror(i) else
    if klaida2=true then showerror(ii);
  end;
   if klaida=false then
   if klaida2=false then
  begin
    if S[i]='(' then chkkab(i,S);
    if S[i]=')' then chkkab2(i,S);
    if klaida=true then showerror(i) else
    if klaida2=true then showerror(ii);
   end;
  end;
 End;

procedure passkab(var s:string; var i,i2:integer); {daje kordynaty konca nawiasow}
  begin
   i:=i+1;
  while s[i]<>')' do
   begin
    if s[i]='(' then passkab(S,i,i);
    i:=i+1;
   end;
   i2:=i;
  end;

procedure subsprendimas(var S:string; var ats:real; var i,i1:integer); { podrozwiaqzywanie w nawiasach}
 var skc,k,mskc,j,i2,strt:integer;
       ch:string;
     ps1:pilnskch;
 Begin
  mskc:=0;
  skc:=0;
  i:=i+1;
  ats:=0;
  strt:=i;

  while S[i]<>')' do
   begin
    ch:='';
  if S[i]='(' then
     begin
      skc:=skc+1;
      mskc:=mskc+1;
      subsprendimas(S,ps1[skc],i,i2);
      i:=i2-1;
     end;
    if S[i] in skchk then
    begin
     skc:=skc+1;
     mskc:=mskc+1;
     while s[i] in skchk do
       begin
        ch:=ch+S[i];
        i:=i+1;
       end;
      val(ch,ps1[skc],k);
      i:=i-1;
         end;
    i:=i+1;
    i1:=i+1;
  end;

  skc:=0;
  i:=strt;
   while S[i]<>')' do
    begin
    if s[i]='(' then passkab(s,i,i);
    if S[i]='+' then
    if S[i-1]<>'(' then skc:=skc+1;
    if S[i]='-' then
    if S[i-1]<>'(' then skc:=skc+1;
    if S[i]='*' then
     begin
      skc:=skc+1;
      (ps1[skc+1]):=(ps1[skc])*(ps1[skc+1]);
      for j:=skc to mskc-1 do
       ps1[j]:=ps1[j+1];
      mskc:=mskc-1;
      skc:=skc-1;
     end;
    if S[i]='/' then
     begin
      skc:=skc+1;
      (ps1[skc+1]):=(ps1[skc])/(ps1[skc+1]);
      for j:=skc to mskc-1 do
       ps1[j]:=ps1[j+1];
      mskc:=mskc-1;
      skc:=skc-1;
   end;
   i:=i+1;
   end;

  skc:=0;
  i:=strt;
  while s[i]<>')' do
   begin
    if s[i]='(' then passkab(s,i,i);
    if S[i]='+' then
    if S[i-1]<>'(' then
     begin
     skc:=skc+1;
     ps1[skc+1]:=ps1[skc]+ps1[skc+1];
     for j:=skc to mskc-1 do
      ps1[j]:=ps1[j+1];
     mskc:=mskc-1;
     skc:=skc-1;
     end;
    if S[i]='-' then
    if S[i-1]<>'(' then
     begin
      skc:=skc+1;
      ps1[skc+1]:=ps1[skc]-ps1[skc+1];
      for j:=skc to mskc-1 do
       ps1[j]:=ps1[j+1];
      mskc:=mskc-1;
      skc:=skc-1;
    end
    else
    ps1[skc+1]:=0-ps1[skc+1];
   i:=i+1;
   end;
   ats:=ps1[mskc];
   for j:=1 to length(s) do ps1[i]:=0;
 End;

Procedure sprendimas(var S:string; var ats:real); {rozwiazywanie ogolne}
  var skc,mskc,i,k,j,i1:integer;
      ch:string;
      ps:pilnskch;
 Begin
  i:=1;
  mskc:=0;
  ats:=0;
  skc:=0;

  while i<=length(S) do
   begin
    ch:='';
    if S[i]='(' then
     begin
      skc:=skc+1;
      mskc:=mskc+1;
      subsprendimas(s,ps[skc],i,i1);
      i:=i1;
      end;
    if S[i] in skchk then
    begin
     skc:=skc+1;
     mskc:=mskc+1;
     while s[i] in skchk do
      begin
       ch:=ch+S[i];
       i:=i+1;
      end;
     val(ch,ps[skc],k);
    end;
   i:=i+1;
   end;

  skc:=0;
  for i:=1 to length(s) do
   begin
   if s[i]='(' then passkab(s,i,i);
   if S[i]='+' then
   if i<>1 then skc:=skc+1;
   if S[i]='-' then
   if i<>1 then skc:=skc+1;
   if S[i]='*' then
   begin
    skc:=skc+1;
    (ps[skc+1]):=(ps[skc])*(ps[skc+1]);
    for j:=skc to mskc-1 do
     ps[j]:=ps[j+1];
    mskc:=mskc-1;
    skc:=skc-1;
   end;
   if S[i]='/' then
   begin
    skc:=skc+1;
    (ps[skc+1]):=(ps[skc])/(ps[skc+1]);
    for j:=skc to mskc-1 do
     ps[j]:=ps[j+1];
    mskc:=mskc-1;
    skc:=skc-1;
   end;
  end;

  skc:=0;
  for i:=1 to length(s) do
   begin
    if s[i]='(' then passkab(s,i,i);
    if S[i]='+' then
    if i<>1 then
    begin
    skc:=skc+1;
    ps[skc+1]:=ps[skc]+ps[skc+1];
    for j:=skc to mskc-1 do
     ps[j]:=ps[j+1];
    mskc:=mskc-1;
    skc:=skc-1;
   end;
    if S[i]='-' then
    if i<>1 then
    begin
     skc:=skc+1;
     ps[skc+1]:=ps[skc]-ps[skc+1];
     for j:=skc to mskc-1 do
      ps[j]:=ps[j+1];
     mskc:=mskc-1;
     skc:=skc-1;
    end
    else
    ps[skc+1]:=0-ps[skc+1];
   end;

   ats:=ps[mskc];
   for i:=1 to length(S) do PS[i]:=0;
 End;

{*********************************************************************}

BEGIN
 Writeln(' Risardo N. PK05A Kalkuliatrius ');
 Writeln;
2:Writeln;
  atsakymas:=0;
  writeln(' Iveskite pilna sprendini apskaiciavimui:');
  readln(tekstas);
  if tekstas='' then goto 21;
  tikrinimas(tekstas);
  if klaida=true then goto 2
  else
  if klaida2=true then goto 2;
  sprendimas(tekstas,atsakymas);
  writeln('Atsakymas lygus: ',atsakymas); {pisze jaka jest odp}
  goto 2;
  readkey;
21:END.

A to jak go przeprowadziłem bez preocedur na sprawdzanie błędów:

//---------------------------------------------------------------------------
#include <vcl.h>
#include <conio.h>
#include <dstring.h>
#include <math.h>
#include <iostream.h>

#pragma hdrstop

//---------------------------------------------------------------------------
#pragma argsused
AnsiString tekstas;
typedef float pilnskch[100];
float atsakymas;
//---------------------------------------------------------------------------
void passkab(AnsiString& S, int& i, int& i2)
 {
   i++;
  while (S[i]!=')')
   {
    if (S[i]=='(') passkab(S,i,i);
    i++;
   }
   i2=i;
 }
//---------------------------------------------------------------------------
void subsprendimas(AnsiString& S, float& ats, int& i, int& i1)
{
 int skc,k,mskc,j,i2,strt;
 AnsiString ch,si;
 pilnskch ps1;
  mskc=0;
  skc=0;
  i++;
  ats=0;
  strt=i;

  while (S[i]!=')')
   {
    ch="";
    si = S[i];
  if (S[i]=='(')
     {
      skc++;
      mskc++;
      subsprendimas(S,ps1[skc],i,i2);
      i=i2-1;
     }
    si = S[i];
    if (si.IsDelimiter("0123456789.",1)==true)
    {
     skc++;
     mskc++;
     while (si.IsDelimiter("0123456789.",1)==true)
       {
        ch=ch+S[i];
        si = S[i];
        i++;
       }
     ps1[skc]=StrToFloat(ch);
     i=i-1;
     si = S[i];
    }
    i++;
    i1=i+1;
  }

  skc=0;
  i=strt;
   while (S[i]!=')')
    {
     if (S[i]=='(') passkab(S,i,i);
     if (S[i]=='+')
      if (S[i-1]!='(') skc=skc+1;
     if (S[i]=='-')
      if (S[i-1]!='(') skc=skc+1;
     if (S[i]=='*')
     {
      skc++;
      (ps1[skc+1])=(ps1[skc])*(ps1[skc+1]);
      for (j=skc; mskc-1;) 
       ps1[j]=ps1[j+1];
      mskc=mskc-1;
      skc=skc-1;
     }
    if (S[i]=='/')
     {
      skc++;
      (ps1[skc+1])=(ps1[skc])/(ps1[skc+1]);
      for (j=skc; mskc-1;)
       ps1[j]=ps1[j+1];
      mskc=mskc-1;
      skc=skc-1;
   }
   i++;
   }

  skc=0;
  i=strt;
  while ( S[i]!=')' )
   {
    if (S[i]=='(')passkab(S,i,i);
    if (S[i]=='+')
    if (S[i-1]!='(')
     {
     skc++;
     ps1[skc+1]=ps1[skc]+ps1[skc+1];
     for (j=skc; mskc-1;)
       ps1[j]=ps1[j+1];      
     mskc=mskc-1;
     skc=skc-1;
     }
    if (S[i]=='-')
    if (S[i-1]!='(')
     {
      skc++;
      ps1[skc+1]=ps1[skc]-ps1[skc+1];
      for (j=skc; mskc-1;) ps1[j]=ps1[j+1];
      mskc=mskc-1;
      skc=skc-1;
     }
    else 
    ps1[skc+1]=0-ps1[skc+1];
   i++;
   }
   ats=ps1[mskc];
   for (j=1;S.Length();) ps1[i]=0;
}
//---------------------------------------------------------------------------
void sprendimas(AnsiString& S, float& ats)
{
 int skc,mskc,i,k,j,i1;
 AnsiString ch,si;
 pilnskch ps;
 i=1;
 mskc=0;
 ats=0;
 skc=0;

 while (i <= S.Length())
  {
  ch="";
  si = S[i];
  if (S[i]=='(')
   {
   skc++;
   mskc++;
   subsprendimas(S,ps[skc],i,i1);
   i=i1;
   }
  si = S[i];
  if (si.IsDelimiter("0123456789.",1)==true)
  {
   skc=skc+1;
   mskc=mskc+1;
   while (si.IsDelimiter("0123456789.",1)==true)
   {
    ch=ch+S[i];
    i=i+1;
    si = S[i];
   }
   ps[skc]=StrToFloat(ch);
  }
  i=i+1;
  si = S[i];
  }

 skc=0;
 for (i=1; S.Length();)
  {
  if (S[i]=='(') passkab(S,i,i);
  if (S[i]=='+')
  if (i!=1) skc++;
  if (S[i]=='-')
  if (i!=1) skc++;
  if (S[i]=='*')
  {
  skc=skc+1;
  (ps[skc+1])=(ps[skc])*(ps[skc+1]);
  for (j=skc; mskc-1;) ps[j]=ps[j+1];
  mskc=mskc-1;
  skc=skc-1;
  }
  if (S[i]=='/')
  {
   skc=skc+1;
   (ps[skc+1])=(ps[skc])/(ps[skc+1]);
   for (j=skc; mskc-1;) ps[j]=ps[j+1];
   mskc=mskc-1;
  skc=skc-1;
  }
 }

 skc=0;
 for (i=1; S.Length();)
  {
  if (S[i]=='(') passkab(S,i,i);
  if (S[i]=='+')
  if (i!=1)
  {
  skc++;
  ps[skc+1]=ps[skc]+ps[skc+1];
  for (j=skc; mskc-1;) ps[j]=ps[j+1];
  mskc=mskc-1;
  skc=skc-1;
  }
  if (S[i]=='-')
  if (i!=1)
  {
   skc++;
   ps[skc+1]=ps[skc]-ps[skc+1];
   for (j=skc; mskc-1;) ps[j]=ps[j+1];
   mskc=mskc-1;
   skc=skc-1;
  }
  else
  ps[skc+1]=0-ps[skc+1]; /* Zauwazylem, ze problem wystepuje tu gdy dochodzi sie do ostatniego symbolu, i tyle. O tu i jest mi potrzeban wasza pomoc.. */
  }

  ats=ps[mskc];
  for (i=1; S.Length();) ps[i]=0;
}

//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
 char txt[512];
 cin>>txt;
 tekstas=txt;
 sprendimas(tekstas,atsakymas);
 getch();
 return 0;
}

Bardzo prosze o rad, troche mi się ta sprawa "pali". ;-)

0

Odpowiadając po temacie: StrToFloat

0

Jezeli przejzysz sie, to zobaczysz, ze to uzywam. Tylko problem w tym jak dochodzi do NULL to juz error wybiwa, ktory mi nic nie mowi.. [glowa]

0

Swoją drogą ciekawe pętle

for (j=skc; mskc-1;) ps[j]=ps[j+1];

for (j=skc; mskc-1;) ps[j]=ps[j+1];
0

Ryszard, ten kod nie jest krótki, nie jest też prosty - też swego czasu pisałem taki parser w C, nawet w kilku wersjach, więc zasadę działania znam. Ale w to nie chce się człowiekowi wgłębiać, kiedy nawet nie wie, CZEGO ma szukać.

Zero komentarzy, zero informacji o błędach, na jakie napotykasz - czeski film, w dodatku po litewsku :]

Pomóż ludziom - opisz to, wyjaśnij działanie (a może właśnie podczas wyjaśniania zrozumiesz, co jest źle!).

0
void subsprendimas(AnsiString& S, float& ats, int& i, int& i1)
{
 int skc,k,mskc,j,i2,strt;
 AnsiString ch,si;
 pilnskch ps1;
  mskc=0;
  skc=0;
  i++;
  ats=0;
  strt=i;

  while (S[i]!=')')
   {
    ch="";
    si = S[i];
  if (S[i]=='(')
     {
      skc++;
      mskc++;
      subsprendimas(S,ps1[skc],i,i2);
      i=i2-1;
     }
    si = S[i];
    if (si.IsDelimiter("0123456789.",1)==true)
    {
     skc++;
     mskc++;
     while (si.IsDelimiter("0123456789.",1)==true)
       {
        ch=ch+S[i];
        si = S[i];
        i++;
       }
     ps1[skc]=StrToFloat(ch); // <- Tu wlasnie wyskakuje problem ***
     i=i-1;
     si = S[i];
    }
    i++;
    i1=i+1;
  }

  • Wlaśnie tu wyskakuje mi bład. W tej funkcji oddzielam float od tekstu. Wszystko idzie dobrze do tych pór, pÓÓÓÓki nie osiaga końca tekstu.
0

Humm... też miałem problem z funkcją StrToFloat, wyskakiwał mi niewiedzieć czemu błąd mówiący że "nie ma czego konwertować". Nie wiem czy Ci to pomoże, użyłem funkcji StrToFloatDef i poszło.

0

Hmm, być może to pomoże, dzięki za radę. Dziś jak znajdę czasu, to sprawdzę. ;-)

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