Runtime error 106

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Derinderinderinerin
Beiträge: 7
Registriert: So 29. Nov 2015, 15:06

Runtime error 106

Beitrag von Derinderinderinerin »

Hallo,
Ganz vorweg : ich bin ein ziemlicher Anfänger was Pascal betrifft. Meine Erfahrungen beschränken sich auf 1 1/2 Jahre Schulunterricht (1 Block pro Woche) nun übe ich auch privat ein wenig...

Zu meinem Problem:
Ich habe versucht eine Übungsaufgabe zu bewältigen (die Berechnung von Nullstellen einer quadratischen Funktion der Form ax²+bx+c)
Soweit so gut,
Ich würde das Programm gerne so benutzerfreundlich wie möglich machen und würde gerne verhindern, dass wenn der benutzer in der eingabeprozedur einen character eingibt (der Datentyp von A, b und c ist real) das Programm den runtime error 106 ausspuckt, sondern eine benutzerdefinierte Fehlermeldung und sich optimalerweise fängt und zur erneuten eingabe von A B und C auffordert

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Runtime error 106

Beitrag von mse »

Wie machst du es denn jetzt?

Derinderinderinerin
Beiträge: 7
Registriert: So 29. Nov 2015, 15:06

Re: Runtime error 106

Beitrag von Derinderinderinerin »

Ich sollte vielleicht erwähnen, dass ich auf dem Smartphone programmiere auf Android, mithilfe der "PascalGUI" App
Ich habe auf verschiedenen Seiten gelesen das es wohl eine "try except end" Struktur gibt aber anscheinend scheint dieser diese nicht zu kennen...


Hier vielleicht noch das Programm :



Code: Alles auswählen

Uses crt;
 
Var a,b,c: real;
Var x : char;
Procedure eingabe;
Begin
  Writeln (
  'Dieses Programm berechnet die Nullstellen einer quadratischen Funktion der Form f(x) = ax²+bx+c'
  ) ;
  Writeln (
'Geben sie die Werte für a, b und c ein und bestätigen Sie diese jeweils einzeln mit der enter taste (in der Reihenfolge a, b, c) '
  ) ;
  Readln (a);
  Readln (b) ;
  Readln (c) ;
End;
Function x1 (a, b, c : real) : real;
Begin
  X1 := -1*((b/a)/2)+sqrt(sqr((b/a)/2)-c/a);
End;
Function x2 (a, b, c : real) : real;
Begin
  X2 := -1*((b/a)/2)-sqrt(sqr((b/a)/2)-c/a);
End;
 
Procedure Ausgabe;
 
Var i : real;
Begin
  i := sqr((b/a)/2)-c/a;
  If i<0 Then
    Begin
      Writeln ('Das Ergebnis unter der Wurzel ist negativ, die Funktion hat somit keine Nullstellen'
      )
    End
  Else
    Begin
      Writeln ('x01= ', x1(a, b, c) : 0: 2);
      Writeln ('x02= ', x2(a, b, c) : 0: 2);
    End;
End;
 
Begin
	Repeat
  Eingabe;
  Ausgabe;
  Writeln ('Weitere Funktion berechnen?') ;
  Writeln ('y= ja    n= nein') ;
  Readln (x);
  Until x='n';
End.
Zuletzt geändert von Lori am Mo 30. Nov 2015, 20:22, insgesamt 1-mal geändert.
Grund: Highlighter

Derinderinderinerin
Beiträge: 7
Registriert: So 29. Nov 2015, 15:06

Re: Runtime error 106

Beitrag von Derinderinderinerin »

Bis jetzt mach ich es garnicht, das ist ja das Problem
Sobald der Nutzer einen falschen Datentyp eingibt stürzt das Programm ab da ja die Zuweisung "real" ist
Und dieses würde ich gerne abfangen

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Runtime error 106

Beitrag von mse »

Dann würde ich zuerst in einen string einlesen (der schluckt alles) und danach mit

Code: Alles auswählen

 
Function TryStrToFloat(Const S : String; Out Value: Double): Boolean;
 
auf real (entspricht double) zu wandeln.
Etwa so:

Code: Alles auswählen

 
var
 str1: string;
 a: real;
...
 readln(str1);
 if not trystrtofloat(str1,a) then begin
  //fehlerbehandlung
 end
 else begin
 //OK
 end;
 
http://www.freepascal.org/docs-html/cur ... float.html

Derinderinderinerin
Beiträge: 7
Registriert: So 29. Nov 2015, 15:06

Re: Runtime error 106

Beitrag von Derinderinderinerin »

Der Datentyp string ist mir sehr neu, tut mir leid wenn die Frage jetzt dämlich rüber kommt... Aber
Laut dem link von dir wandelt diese function den string in real um und wenn es erfolgt ist gibt sie dann eine Boolean Variable aus jenachdem true oder false...

Nur die Struktur ist mir nicht ganz ersichtlich? Was gebe ich der function "unter ihr"?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Runtime error 106

Beitrag von mse »

Was meinst du mit "function "unter ihr""?
String ist ein Datentyp zur Speicherung von Zeichenketten. In unserem Fall werden die eingegebenen Buchstaben gespeichert.

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Runtime error 106

Beitrag von Mathias »

das Programm den runtime error 106 ausspuckt, sondern eine benutzerdefinierte Fehlermeldung
Wen du noch nicht mit Strings hantieren willst, kannst es ganz einfach haben:

Code: Alles auswählen

program Project1;
var
  r: real;
begin
{$i-}   // Dies schaltet die automatische Fehlermeldung aus.
  ReadLn(r);
  if IOResult <> 0 then begin
    Writeln('Keine gueltige Zahl');
  end else begin
    WriteLn('Die Zahl lautet: ', r);
  end;
end.
Aber wen es Benutzerfreundlich sein soll, wieso machst du nicht ein Formular mit Eingabefeldern (TEdit) ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Derinderinderinerin
Beiträge: 7
Registriert: So 29. Nov 2015, 15:06

Re: Runtime error 106

Beitrag von Derinderinderinerin »

Mit unter ihr meine ich die Function selbst, sie kann doch nicht nur aus einer Kopfzeile mit formalen Parametern bestehen

Mit strings würde ich schon gerne arbeiten das hört sich auch nützlich an nur versteh ich nicht ganz den Ablauf der Konvertierung


Wie gesagt ich kenn mich einfach noch garnicht aus mit Pascal, stehe sozusagen in den Startlöchern, schulisch gesehen behandeln wir erst nächste Woche Arrays und hatten davor halt nur schleifen und das variablenkonzept

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Runtime error 106

Beitrag von Mathias »

Ich sollte vielleicht erwähnen, dass ich auf dem Smartphone programmiere auf Android, mithilfe der "PascalGUI" App
Das habe ich übersehen, diese App habe ich auch. Ist etwas mühsam in der Bedienung.
Mit unter ihr meine ich die Function selbst, sie kann doch nicht nur aus einer Kopfzeile mit formalen Parametern bestehen
Die muss auch nicht eingegeben werden, dies ist nur ein Muster, das du die Parameter siehst.
Wie gesagt ich kenn mich einfach noch garnicht aus mit Pascal, stehe sozusagen in den Startlöchern
Da würde ich dies mit IOResult vorziehen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Runtime error 106

Beitrag von mse »

Sorry, das habe ich ungeschickt geschrieben. Das Zitat ist die Definition des Funktionskopfs wie sie in der Free Pascal Bibliothek steht, daraus kann man den Aufruf ablesen. Der erste Parameter ist ist ein Eingabestring, in den zweiten Parameter wird das Resultat der Umwandlung geschrieben.
Der Aufruf ist wie bereits geschrieben:

Code: Alles auswählen

 
...
 if not trystrtofloat(str1,a) then begin
...
 
Wenn du ohne Umwandlungsfunktion auskommen möchtest ist die Methode von Mathias das Richtige.

Die komplette Bibliotheksfunktion ist übrigens so:

Code: Alles auswählen

 
Function TryStrToFloat(Const S : String; Out Value: Double): Boolean;
 
begin
  Result:=TryStrToFloat(S,Value,DefaultFormatSettings);
end;
 
dann:

Code: Alles auswählen

 
Function TryStrToFloat(Const S : String; Out Value: Double; Const FormatSettings: TFormatSettings): Boolean;
Begin
  Result := TextToFloat(PChar(pointer(S)), Value, fvDouble,FormatSettings);
End;
 
dann:

Code: Alles auswählen

 
Function TextToFloat(Buffer: PChar; Out Value; ValueType: TFloatValue; Const FormatSettings: TFormatSettings): Boolean;
 
Var
  E,P : Integer;
  S : String;
{$ifndef FPC_HAS_STR_CURRENCY}
  TempValue: extended;
{$endif FPC_HAS_STR_CURRENCY}
 
Begin
  S:=StrPas(Buffer);
  //ThousandSeparator not allowed as by Delphi specs
  if (FormatSettings.ThousandSeparator <> FormatSettings.DecimalSeparator) and
     (Pos(FormatSettings.ThousandSeparator, S) <> 0) then
    begin
      Result := False;
      Exit;
    end;
  if (FormatSettings.DecimalSeparator <> '.') and
     (Pos('.', S) <>0) then
    begin
      Result := False;
      Exit;
    end;
 
  P:=Pos(FormatSettings.DecimalSeparator,S);
  If (P<>0) Then
    S[P] := '.';
  case ValueType of
    fvCurrency:
{$ifdef FPC_HAS_STR_CURRENCY}
      Val(S,Currency(Value),E);
{$else FPC_HAS_STR_CURRENCY}
      begin
        // needed for platforms where Currency = Int64
        Val(S,TempValue,E);
        Currency(Value) := TempValue;
      end;
{$endif FPC_HAS_STR_CURRENCY}
    fvExtended:
      Val(S,Extended(Value),E);
    fvDouble:
      Val(S,Double(Value),E);
    fvSingle:
      Val(S,Single(Value),E);
    fvComp:
      Val(S,Comp(Value),E);
    fvReal:
      Val(S,Real(Value),E);
  end;
  Result:=(E=0);
End;
 
dann:

Code: Alles auswählen

 
Function fpc_Val_Real_AnsiStr(Const S : AnsiString; out Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_ANSISTR']; compilerproc;
Var
  SS : String;
begin
  fpc_Val_Real_AnsiStr := 0;
  if length(S) > 255 then
    code := 256
  else
    begin
      SS := S;
      Val(SS,fpc_Val_Real_AnsiStr,code);
    end;
end;
 
dann:

Code: Alles auswählen

 
Function fpc_Val_Real_ShortStr(const s : shortstring; out Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_SHORTSTR']; compilerproc;
var
  hd,
  esign,sign : valreal;
  exponent,
  decpoint,i : SizeInt;
  flags      : byte;
begin
  fpc_Val_Real_ShortStr:=0.0;
  code:=1;
  exponent:=0;
  decpoint:=0;
  esign:=1;
  flags:=0;
  sign:=1;
  while (code<=length(s)) and (s[code] in [' ',#9]) do
    inc(code);
  if code<=length(s) then
    case s[code] of
     '+' : inc(code);
     '-' : begin
             sign:=-1;
             inc(code);
           end;
    end;
  while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
    begin
   { Read integer part }
      flags:=flags or 1;
      fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
      inc(code);
    end;
{ Decimal ? }
  if (length(s)>=code) and (s[code]='.') then
    begin
      inc(code);
      while (length(s)>=code) and (s[code] in ['0'..'9']) do
        begin
           { Read fractional part. }
          flags:=flags or 2;
          fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
          inc(decpoint);
          inc(code);
        end;
   end;
 { Again, read integer and fractional part}
  if flags=0 then
    begin
      fpc_Val_Real_ShortStr:=0.0;
      exit;
    end;
 { Exponent ? }
  if (length(s)>=code) and (s[code] in ['e','E']) then
    begin
      inc(code);
      if Length(s) >= code then
        if s[code]='+' then
          inc(code)
        else
          if s[code]='-' then
           begin
             esign:=-1;
             inc(code);
           end;
      if (length(s)<code) or not(s[code] in ['0'..'9']) then
        begin
          fpc_Val_Real_ShortStr:=0.0;
          exit;
        end;
      while (length(s)>=code) and (s[code] in ['0'..'9']) do
        begin
          exponent:=exponent*10;
          exponent:=exponent+ord(s[code])-ord('0');
          inc(code);
        end;
    end;
{ adjust exponent based on decimal point }
  if esign>0 then
    begin
      dec(exponent,decpoint);
      if (exponent<0) then
        begin
          esign:=-1;
          exponent:=-exponent;
        end
    end
  else
    inc(exponent,decpoint);
{ evaluate sign }
{ (before exponent, because the exponent may turn it into a denormal) }
  fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*sign;
 
{ Calculate Exponent }
  hd:=1.0;
  { the magnitude range maximum (normal) is lower in absolute value than the }
  { the magnitude range minimum (denormal). E.g. an extended value can go    }
  { up to 1E4932, but "down" to 1E-4951. So make sure that we don't try to   }
  { calculate 1E4951 as factor, since that would overflow and result in 0.   }
  if (exponent>valmaxexpnorm-2) then
    begin
      for i:=1 to valmaxexpnorm-2 do
        hd:=hd*10.0;
      if esign>0 then
        fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*hd
      else
        fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
      dec(exponent,valmaxexpnorm-2);
      hd:=1.0;
    end;
  for i:=1 to exponent do
    hd:=hd*10.0;
  if esign>0 then
    fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*hd
  else
    fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
 
{ Not all characters are read ? }
  if length(s)>=code then
    begin
      fpc_Val_Real_ShortStr:=0.0;
      exit;
    end;
{ success ! }
  code:=0;
end;
 
Spassig was es zum Umwandeln von Text zu Fliesskommazahl alles braucht, nicht? ;-)

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Runtime error 106

Beitrag von Mathias »

Spassig was es zum Umwandeln von Text zu Fliesskommazahl alles braucht, nicht?
Ausser, man nimmt val, die ist direkt im System eingebaut.
Interessant daran, der viele Code verwendet am Ende auch nur val.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Derinderinderinerin
Beiträge: 7
Registriert: So 29. Nov 2015, 15:06

Re: Runtime error 106

Beitrag von Derinderinderinerin »

Also ist "TryStrToFloat" sozusagen vordefiniert und ich kann sie überall aufrufen und brauch sie nur mit den Parametern Füttern?

Und wenn sie mit einem string gefüttert wird der eine Zahl enthält dann wandelt diese sie um und gibt true aus umgekehrt false

Kann ich das dann einfach so schreiben :

If TryStrToFloat (str1,a)=true then
Begin
//Berechnungen
End;
Else
//Fehlermeldung

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Runtime error 106

Beitrag von Mathias »

Es geht sogar noch ein bisschen einfacher.

Code: Alles auswählen

If TryStrToFloat (str1,a) then
Begin
//Berechnungen 
End
Else
//Fehlermeldung
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Derinderinderinerin
Beiträge: 7
Registriert: So 29. Nov 2015, 15:06

Re: Runtime error 106

Beitrag von Derinderinderinerin »

Gut dann habe ich noch die letzte Frage : wird mit dem "if TryStrToFloat...." gleichzeitig der Tausch ausgeführt? Da mein Programm ja nicht mit strings rechnen kann oder?

Edit: ich hab es gerade mal in einem simplen Programm ausprobiert,es scheint als ob die "pascalgui" App die vordefinierte funktion nicht besitzt... Es kommt nur "unknown identifier "TryStrToFloat" "beim Compiling

Antworten