| Autor |
Beitrag |
matze
      
Beiträge: 4613
Erhaltene Danke: 24
XP home, prof
Delphi 2009 Prof,
|
Verfasst: Mi 04.02.09 10:51
Hallo.
Ich habe mal eine blöde Frage, bei der ich ein wenig auf dem Schlauch stehe. Und zwar: Ich habe 2 Strings mit Versionsnummern in der Form: '1.0.1.19' oder '2.5.3.0'.
Wie kann ich diese denn am einfachsten miteinander vergleichen um herauszufinden, welche von beiden höher ist?
Da einzelne Elemente der Nummern ja auch 2-stellig sein können, kann ich nicht einfach alle Punkte rauswerfen und dann den String als Integer interpretieren.
Ich steh da grade echt auf dem Schlauch und das ist mir auch richtig peinlich. Ich hoffe, ihr könnte mir helfen.
Danke!
Matze
_________________ In the beginning was the word.
And the word was content-type: text/plain.
|
|
Regan
      
Beiträge: 2157
Erhaltene Danke: 72
Java (Eclipse), Python (Sublimetext 3)
|
Verfasst: Mi 04.02.09 10:55
Ist vielleicht die speicherreichste Lösung: Einzelne Strings erstellen (zwischen den Punkten) und die dann nach Integer konvertieren.
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 04.02.09 10:56
Zerleg den String am Punkt in 4 einzelne Bytes. Durch BitShifting bekommst Du dann eine 32-bittige Zahl, die Du direkt vergleichen kannst.
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mi 04.02.09 11:01
Ich habe vor kurzem dasselbe Problem gehabt und es einfach mit Copy, Pos und PosEx gelöst. D.h. die Zahlen bis zum ersten Punkt verglichen, dann die zwischen dem ersten und zweiten usw. Beim ersten "<>" wird abgebrochen, und man hat die Info, ob es ein major, minor oder sonstwas Update ist.
Vielleicht nicht besonders elegant, aber das ist ja auch keine Funktion, die besonders schnell sein muss. Der Flaschenhals bei der Gesamtfunktion dürfte ja sehr deutlich der Abruf der einen Versionsnummer aus dem Netz sein. 
_________________ We are, we were and will not be.
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 04.02.09 11:04
"<>" ist aber der falsche Vergleich, dann würdest Du ja evtl. mit einer älteren Version updaten.
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mi 04.02.09 11:12
Natürlich kommt da nicht nur "<>". Aber wenn die Überprüfung auf "=" das erste Mal fehlschlägt, hat man die Stelle im Versionsstring identifiziert, die über Up- oder Downgrade entscheidet. Die folgenden Ziffern sind dann uninteressant.
_________________ We are, we were and will not be.
|
|
matze 
      
Beiträge: 4613
Erhaltene Danke: 24
XP home, prof
Delphi 2009 Prof,
|
Verfasst: Mi 04.02.09 11:21
Kannst du mir diese Funktion vielleicht mal schicken? Bitte?
(Leider haben wir keinen "Hundeblick"-Smiley in der Liste)
_________________ In the beginning was the word.
And the word was content-type: text/plain.
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mi 04.02.09 11:32
Ich kann die heute abend mal posten, wenn ich wieder zuhause bin. Allerdings vergleiche ich bei mir auch nicht direkt zwei Strings, sondern einen String mit der Versionsinfo, die in die Exe einkompiliert wurde.
Kompliziert ist die nicht, aber wenn ich die jetzt runtertippe, habe ich bestimmt einige "+/- Eins-Fehler" bei den Indizes und Längen drin. 
_________________ We are, we were and will not be.
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Mi 04.02.09 13:23
Oder du teilst in die einzelnen Gruppen auf, wandelst zum Integer um und potenzierst:
Quelltext 1: 2:
| 1.0.1.19 -> 1 0 1 19 -> (1 * 99^3) + (0 * 99^2) + (1 * 99^1) + (19 * 99^0) = 970299 + 0 + 99 + 19 = 970417 2.5.3.0 -> 2 5 3 0 -> (2 * 99^3) + (5 * 99^2) + (3 * 99^1) + ( 0 * 99^0) = 1940598 + 49005 + 297 + 0 = 1989900 |
Geht natürlich davon aus, dass 99 jeweils der maximale Wert ist (99.99.99.99 = 97039800). Wenn dir die Zahlen nicht zu groß sind (kA wie das mit der Laufzeit ist), wäre das auch eine Möglichkeit, ansonsten gefällt mir auch der Vorschlag von DeddyH.
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mi 04.02.09 13:37
In Windows (VS_FIXEDFILEINFO) werden die 4 Werte als 64-bit Wert gehandhabt. Würde also für die einzelnen Werte mindestens ein Word nehmen.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 04.02.09 14:07
DeddyH hat folgendes geschrieben : | | Zerleg den String am Punkt in 4 einzelne Bytes. Durch BitShifting bekommst Du dann eine 32-bittige Zahl, die Du direkt vergleichen kannst. |
Das hab ich mal schnell im Browser runtergeschrieben, sollte so hoffentlich stimmen, delfiphans Zusatz hab ich mal berücksichtigt: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| function CompareVersions(const Ver1, Ver2: String): Integer;
function VerToInt(const Value: String): Int64; var a, b: Integer; begin Result := 0; a := 1; b := 1; while (b < Length(Value)) and (Value[b] <> '.') do Inc(b); Result := Result + (StrToInt64(Copy(Value, a, b - a)) shl 48); a := b + 1; while (a < Length(Value)) and (Value[a] <> '.') do Inc(a); Result := Result + (StrToInt64(Copy(Value, b + 1, a - b - 1)) shl 32); b := a + 1; while (b < Length(Value)) and (Value[b] <> '.') do Inc(b); Result := Result + (StrToInt64(Copy(Value, a + 1, b - a - 1)) shl 16); Result := Result + StrToInt(Copy(Value, b + 1, Length(Value) - b)); end;
var Val1, Val2: Int64; begin Val1 := VerToInt(Ver1); Val2 := VerToInt(Ver2); if Val1 < Val2 then Result := -1 else if Val1 = Val2 then Result := 0 else Result := 1; end; |
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 04.02.09 14:33
Naja, bliebe noch die Frage für Linux-Versionsstrings (hier Beispiele von Debian, andere Distries sind weitestgehend kompatibel):
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| 1 < 1.2 1.1 < 1.2 1.2.3 < 1:1.2.3 1.2 < 1.2-3 1.2 < 1.2a 1.2-3 < 1.2.3-1 1.2a3 < 1.2b1 1:9.9 < 2:0.0.1 1:1.2.3.3.dfsg-12 > 1:1.2.3-13 |
Wichtig ist hier die Epoch-Behandlung (Die Zahlen vor dem Doppelpunkt) sowie das Patchlevel-Handling. Hat da ggf. jemand nen Link mit den genauen Regeln parat? Ggf. kann man die Versionsvergleicherei nämlich gleich mit einer Routine abdecken und ggf. einfach das Muster\den Regelsatz mitgeben (sprich APT-Regeln, PHP-Regeln, Windows-Regeln, ...)
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 04.02.09 14:54
|
|
matze 
      
Beiträge: 4613
Erhaltene Danke: 24
XP home, prof
Delphi 2009 Prof,
|
Verfasst: Do 05.02.09 09:12
Woah. Ich bin ganz erschlagen.
Ihr habt mir auf jeden Fall geholfen! Wie gesagt: Das Problem war ja nicht so komplex, ich stand einfach nur auf dem Schlauch
Vielen Dank. Ich habe nur jetzt leider kein Delphi da um es zu testen, aber ich werde mir die Codes am Abend oder am Wochenende mal zu Gemüte führen!
Matze
PS: @ BenBE: Danke für den Hinweis, aber ich beschränke mich mal auf die Windows-Dateiversionsnummern X.X.X.X
_________________ In the beginning was the word.
And the word was content-type: text/plain.
|
|