![]() |
"Cardinal-String" zurück in Cardinal: Exception
Hallo,
ich weiß nicht, warum ich diesem Fehler, den ich da wohl mache, noch nie begnet bin, aber jetzt ist es soweit. Folgendes läuft ab: Ich habe in meinem Programm eine Variable vom Typ Cardinal. Diese wandle ich - um sie in einem Textfile zu speichern - in einen String um. Wenn ich dann diesen String wieder auslesen und meiner Variablen zuweisen will, kommt immer ein Fehler wenn die Variable Größer als
Delphi-Quellcode:
ist, was ja bei Cardinal möglich ist.
high(Integer)
Ich habe einen einfachen Code geschrieben um den Fehler reproduzieren zu können:
Delphi-Quellcode:
Was mache ich falsch? Es gibt doch keine StrToCardinal oder so :-(
function CardinalStringException: String
var c1,c2: Cardinal; s: String; begin c1 := 1; c1 := c1 + high(Integer); s := IntToStr(c1); c2 := StrToInt(s); // --> hier tritt der Exception auf :-( result := IntToStr(c2); end; Vielen Dank für Eure Hilfe. [Edit] Titel angepasst [/Edit] |
Re: "Cardinal-String" zurück in Cardinal
Delphi-Quellcode:
oder
Unit: IdGlobal
function StrToCard(AVal: String): Cardinal; Parameters AVal: String the string containing a numerical value. Returns Cardinal - The value the string was converted to. Description This function converts a string value into a cardinal (a 32-bit unsigned value) after stripping off spaces and other control characters.
Delphi-Quellcode:
Grüße
Converts a string that represents an integer (decimal or hex notation) to a number.
Unit SysUtils Category type conversion routines function StrToInt64(const S: string): Int64; Description StrToInt64 converts the string S, which represents an integer-type number in either decimal or hexadecimal notation, into a number. If S does not represent a valid number, StrToInt64 raises an EConvertError exception. Klaus |
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Hallo Klaus,
danke erstmal für die schnelle Antwort. Aber diese Methode gehört doch in den Bereich Indy. Auszug aus der Hilfe: Common routines and classes used in the Indy component suite. Ich suche eigentlich eine "Übliche Methode". Vorallem wenn man ein Ini-File (TIniFile) nutzt und dort die Methoden WriteInteger bzw. ReadInteger benutzt gibts auch Fehler. Also was kann man da mit Standardmethoden o.ä. tun? Die Int64 -Methode ist gut, aber die ist doch "eigentlich" eben nur für Int64. Naja, egal sie tut Ihren zweck. Aber das mit dem Inifiles tut da leider immer noch nicht. MAn muss halt erst in nene Temporären String wandeln und dann schreiben bzw. anderesrum beim Lesen. Danke nochmals für die super schnelle Antwort :-) Wenn jemand nochwas weiß / hat, immer her damit - vorallem wegen dem Inifile. THX |
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Also willst du eine Cardinal-Variable in 'ner INI speichern, welche ja "nur" Integer annimmt ... hab ich dat richtig verstanden? :gruebel:
Dann tu doch einfach so, als wenn der Cardinal ein Integer wäre ^^
Delphi-Quellcode:
Var C: Cardinal;
Ini.ReadInteger('...', '...', Integer(C)); Ini.WriteInteger('...', '...', Integer(C)); |
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Dann leite doch das Object TIni ab und gebe ihm noch die Methode die fehlt.
Nur ein Ansatz:
Delphi-Quellcode:
function ReadCardinal(const Section, Ident: String; Default: Cardinal): cardinal;
var s:String; begin s:=ReadString(section,ident,0); result:=StrToInt64(s); // vielleicht noch auf cardinal casten end; @ Himitsu aber was ist wenn C größer als max Integer ist? Grüße Klaus |
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Das Problem ist, das die API Funktionen für die veralteten IniFiles nicht mitspielen. Ich würde TMemIniFile verwenden und alle anderen Vorteile genießen, die diese Klasse mitbringt:
Delphi-Quellcode:
Grüße vom marabu
procedure TDemoForm.ExtraGridClick(Sender: TObject);
var c: Cardinal; begin with TMemIniFile.Create(ExtractFilePath(ParamStr(0)) + 'temp.ini') do begin ShowMessage(IntToHex(MaxInt, 8)); c := Cardinal(MaxInt) shl 1; WriteInteger('test', 'card', c); c := ReadInteger('test', 'card', 0); ShowMessage(IntToHex(c, 8)); Free; end; end; |
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Zitat:
|
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Zitat:
Zitat:
Zitat:
Vielen Dank an alle. Ihr habt mir - wie immer - sehr gut weiter geholfen :-) |
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Gleiches Problem hatte ich auch und warum ist ja nun schon gut erklärt worden. Andere Lösung dazu, welche ich damals gefunden habe:
Str() und Val() sind typspezifisch und arbeiten richtig. Grundlegendes Problem hast du nämlich, wenn du eine Zahl die als String vorliegt und > High(Integer) (MaxInt) ist aber auch gleichzeitig < High(Cardinal) ist - diese wird mit StrToInt nicht ordentlich konvertiert und IntToStr64() löst u.U. unerklärlicherweise trotzdem eine ERangeCheck Exception aus (obwohl es eigentlich ohne Problem klappen sollte) (bei eingeschalteter Bereichsprüfung). Die Val() Funktion arbeitet hingegen fehlerfrei und wandelt auch die Zahlen in dem o.g. Bereich sauber in vorzeichenlose 32 Bit Ganzzahlen um. Str() ist auch das passende Gegenstück, welches richtige Zahlen aus Cardinaltypen ohne Vorzeichen mit der richtigen Grösse erstellt. |
Re: "Cardinal-String" zurück in Cardinal: Exceptio
Zitat:
Cardinal liegt ja irgendwo im Speicher rum und ist 4 Byte (32 Bit, bei den "aktuellen" 32-Bit-Compilern) groß. Nun ist es dem Speicher aber vollkommen egal was er ist ... das Was kommt erst zu stande, wenn er intepretiert wird, also wenn irgendwas festlegt was welches Bit zu bedeuten hat und wie diese zusammenarbeiten. Nun ist allerdings ein Integer auch 4 Byte groß demnach kann man ganz locker diese 4 Byte auch mal als Integer interpretieren, oder auch mal als Single (ist ja auch nur ein 4-Byte-Real-Wert), oder wie wäre es mal als Array[0..3] ob Byte? ... alles was gleich groß ist, kann man direkt umwandeln. Dieses Integer(C), oder Cardinal(i) macht also nichts anders, als den Inhalt der Veriable umzuwandeln, oder besser gesagt anders zu interpretieren. Das praktische am Integer und Cardinal ist ja auch noch der Umstand, daß deren Formate eigentlich fast gleich sind ... beim Cardinal wird jedem Bit eine Wertigkeit zugeordnet und diese dann addiert, was beim Integer eigentlich genauso ist, nur daß halt da das höchste Bit nicht als Wert, sondern als das Vorzeichen verwendet wird ... somit macht man alao nur mit Integer(C) das höchste Bit, welches im Cardinal den Bereich über MaxInt darstellt das Vorzeichen, also den Bereich unter MinCardinal. PS: öffne einfach mal deinen Windowstaschenrechner, stell den auf Wissenschaftlich um und gib den Wert für MinInt ein (kannst'e aus der OH kopieren), dann stell den Taschenrechner auf Hexadezimal um und wieder zurück auf Dezimal ... und schwupps steht da der Wert für MaxInt + 1, da dieser Taschenrechner mit 64 Bit rechnet und somit die unteren 4 Bytes sozusagen als Cardinal gelesen werden, wenn sie aus dem Hexadezimalen kommen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz