Roland Goretzki schrieb:
der Fehler lag in der falschen Deklaration einer Variablen, die nicht Integer, sondern LongInt sein mußte:
Ist so etwas auch ein Laufzeitfehler?
Kommt darauf an, was der Fehler war:
- Wenn er beim Compilieren (gpc-Aufruf) auftritt, ist es ein Compile-Fehler (z.B. wenn als var-Parameter Integer statt LongInt übergeben wird oder umgekehrt; während Wert-Parameter automatisch umgewandelt werden).
- Wenn er beim Programmaufruf auftritt, ist es ein Laufzeitfehler, z.B. weil eine Berechnung überläuft, die LongInt erfordern würde.
Du schriebst:
Demnach müßte ich also für das 2. Argument die Variable eins einsetzen:
eins := 1; Leistung [eins] := StrReadInt (Leistungs_Zahl [drei], eins, Leistung [eins]);
Das erste Argument ist der String, aus dem ich die Zahl haben möchte. Vielleicht ist das 3. Argument der springende Punkt. Mir ist überhaupt nicht klar, weshalb noch ein 3. Argument gebraucht wird, also auch nicht, was da erwartet wird.
Das 3. Argument ist das Ziel, soweit richtig.
Das heißt, daß dort genau dasselbe stehen muß wie das, dem ich es zuweisen möchte? Klingt merkwürdig, habe ich aber im obigen Beispiel probiert, weil mir nichts Besseres einfiel.
Du wunderst dich vermutlich eher über das 2. Argument.
Nein, nach dem gründlicheren Studium der Funktion ist mir das mit dem Positionszähler schon einigermaßen klar geworden.
Wenn ich die obige Zeile:
Leistung [eins] := StrReadInt (Leistungs_Zahl [drei], eins, Leistung [eins]);
so schreibe:
Leistung [1] := StrReadInt (Leistungs_Zahl [drei], eins, Leistung [1]);
dann müßte es klarer sein. Aber auch dann heißt es: "incompatible types in assignment". Was ist denn da noch falsch?
Oder über den Rückgabewert:
: They return True if successful, False otherwise.
Deshalb klappt die Zuweisung an die Zielvariable nicht.
Es gibt ja gar keinen Rückgabewert, nur die obige Fehlermeldung.
Da liegen wohl ein paar Missverständnisse vor. Der Rückgabewert ist der Wert, den die Funktion liefert. In diesem Fall ist der Rückgabewert eben ein Boolean (der angibt, ob die Umwandlung erfolgreich war oder nicht) und eben nicht das Ergebnis der Umwandlung. Dieses wird in dem 3. Parameter zurückgeliefert. Deshalb muss als 3. Parameter eben das Ziel (in deinem Fall "Leistung[eins]") übergeben werden -- nicht auch, sondern nur dort, während der Rückgabewert abgefragt werden kann, um Fehler zu erkennen. Wie gesagt, s. das Beispiel in dem Kommentar, dort werden die Zielvariablen ("Size", "Name", ...) ja auch nur an einer Stelle verwendet und die Rückgabewerte im "if" abgefragt.
Der Sinn ist, dass man auf diese Weise mehrere Werte aus einem String auslesen kann (was ja, wie gesagt der Hauptzweck dieser Funktionen ist) und die Fehlerabfrage einfach mit "and" kombinieren kann, damit man nicht für jeden einzelnen Wert eine Fehlerbehandlung schreiben muss (solange es einen nur interessiert, ob die Umwandlungen komplett erfolgreich sind oder nicht).
Oder bedeutet diese Fehlermeldung schon ein "return False"?
Nein, die Fehlermeldung kam ja beim Compilieren und Rückgabewerte ist das, was zur Laufzeit passiert (vgl. oben).
Dann kannst du auch einfach "ReadStr" verwenden. Wenn er dann doch etwas anderes enthält, gibt es einen Laufzeitfehler. Je nach Anwendung ist das OK oder nicht ...
So scheint es. Zwar habe ich in einem kleinen Probe-Programm vorhin problemlos gearbeitet, aber mein großes Programm läuft genau dann nicht mehr, wenn ich die Zeile mit Str2Int einkommentiere, obwohl bei der Übersetzung nichts beanstandet wird (Das ist ja wohl en Laufzeitfehler, oder?).
Was heißt, es läuft nicht mehr?
Laufzeitfehler sehen so ähnlich aus:
foo: sign or digit expected (error #552 at 804a0b6)
Wenn es immer noch um das CGI-Programm geht, sieht man im Browser nur einen internen Fehler (500 oder so), wenn das Progrmam vorzeitig abbricht. Die genaue Fehlermeldung findet man ggf. im Server-Logfile.
Nein, es stürzt nicht ab. Nur wird die html-Ausgabe nicht mehr vollständig aufgebaut, d.h. ich bekomme nicht das, was ich wollte, sondern er schreibt ab einem gewissen Punkt den html-Code nicht mehr weiter.
OK, das passiert, wenn er schon in mitten in der HTML-Ausgabe ist. Trotzdem steht die Fehlermeldung im Apache-Log (/var/log/apache/www.roland-goretzki.de-error_log -- habe mir mal erlaubt nachzusehen :-).
Zur noch genaueren Prüfung habe ich mal etwas in eine Probedatei geschrieben::
Append (ProbeDat, '../test/LST/die-Sitzungen/probe.txt'); WriteLn (ProbeDat, Rekord_Datum); Close (ProbeDat); ReadStr (Rekord_Datum, Das_Rekord_Datum);
Das funktioniert, wenn ich die Datei VOR der ReadStr-Anweisung beschreibe.
Es findet kein weiterer Schreibvorgang statt, wenn ich die Datei NACH der ReadStr-Anweisung beschreiben will.
Ja, so kann man die Fehlerstelle einkreisen, wenn auch umständlich. Mit der Fehlermeldung aus dem Log (oder bei nicht-CGI-Programmen direkt in der Fehlerausgabe) ist oft sofort klar, was los ist. Ansonsten enthält sie auch noch eine Positionsangabe wie "(error #452 at 806407f)". Diese kann man mit folgendem Programm einer Programmzeile zuordnen:
addr2line -e program 806407f
"program" ist dabei das compilierte Programm. Wichtig ist dabei, dass es mit "-g" (Debug-Info) compiliert wurde und seit dem Auftreten des Fehlers nicht verändert wurde (sonst verschieben sich die Positionen).
Frank