cString -> Unique Nummer ?

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12910
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

cString -> Unique Nummer ?

Beitrag von AUGE_OHR »

hi,

ich möchte für eine cString eine eindeutige 6 stellige Nummer(?) erstellen.

Code: Alles auswählen

FUNCTION NumNam(cString)
LOCAL RETVAR := 0
LOCAL i,iMax := LEN(ALLTRIM(cString))
LOCAL xVal

   FOR i = 1 TO iMax
      xVal := SUBSTR(cString,i,1)
      IF VAL(xVal) > 0
         RETVAR := RETVAR+(VAL(xVal) *i)
      ELSE
         RETVAR := RETVAR+(Asc(xVal) *i)
      ENDIF
   NEXT

RETURN STRZERO(RETVAR,6)
obwohl ich zwar 999999 Möglichkeiten hätte scheint mir das Ergebniss
nicht unbedingt eindeutig zu sein, oder ?

hat sonst jemand eine Idee ?

gruss by OHR
Jimmy
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Jimmy,

muss die Zahl 6-stellig, oder darf's auch mehr sein? Sind auch hexadezimale Ziffern erlaubt?

Wenn ja, wäre CoCreateGuid aus Ole32.dll vielleicht eine Möglichkeit.

Viele Grüße,
Günter
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12910
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,

ich hätte vielleicht mal sagen sollen wofür ich es haben möchte :

also ich bin immer noch einer von denen die in der CMD Box hantieren.
Ergo bin ich auch noch bei 8.3 Dateinamen (wenn es geht).

Nun will ich Bilder Namen in 8.3 erstellen, wobei das 1st Zeichen ein
Buchstabe sein sollte und der letzte ebenfalls. Deshalb in der Mitte
dann 6 Zeichen.

das ganze muss auf allen Codepage (chinesich/deutsch/englisch)
lauffähig sein, deshalb kam ich auf Ziffern statt String.
Günter Beyes hat geschrieben: muss die Zahl 6-stellig, oder darf's auch mehr sein? Sind auch hexadezimale Ziffern erlaubt?
ich bin mir nicht mehr sicher was das Problem bei Cl*pper war wenn
das 1st Zeichen eine Ziffer war. Das 8st Zeichen ist lediglich ein "A"
oder "B" was Anfang/Ende kennzeichenen soll. (es gehören immer 2
Bilder zusammen)

Hexadezimal währe auch ok.

wichtig ist nur das ich aus DOS/CMD den Dateinamen 8.3 als Parameter
benutzen kann um damit ein SEEK() zu starten wenn ich aus dem Norton
Commander etc. meine Xbase++ Application starte.

Code: Alles auswählen

Procedure Main(cSuch)
  IF PCOUNT() > 0
      SEEK(cSuch)
...
Günter Beyes hat geschrieben: Wenn ja, wäre CoCreateGuid aus Ole32.dll vielleicht eine Möglichkeit.
hm ... ich hab mal im Alaska Forum geforscht was GUID überhaupt ist.
sehe ich das richtig das man damit das Format
{nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}
meint wie es auch in der Registry verwendet wird ?

gruss by OHR
Jimmy
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Jimmy,
was spricht gegen GetUniqueFileName()?
(seit Version 1.9)

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jimmy,
oder - noch besser - selber machen!
Ungetestet (und mal eben nach dem Aufstehen aus dem Kopf gepurzelt):

Code: Alles auswählen

nNumber := 0
aFnames := Directory( cVerz + "????????." + cEndung )
if len( aFnames ) > 0
  asort( aFnames, { |x1, x2 | val( substr( x1[ F_NAME ], 2, 6 ) ) > val( substr( x2[ F_NAME ], 2, 6 ) ) } )
  nNumber := val( substr( aFnames[ 1, F_NAME ], 2, 6 ) )
endif
cMiddleFname := right( strzero( nNumber, 7 ), 6 )
Viele Grüße,
Martin
Zuletzt geändert von Martin Altmann am Fr, 15. Jun 2007 9:00, insgesamt 1-mal geändert.
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Martin,

ebenfalls mal eben so aus dem Kopf gepurzelt:

Ich weiß ja nicht, was die Funktion GetUniqueFileName() intern macht, aber würde Dein Vorschlag nicht bei größeren Filemengen etliches an Zeit benötigen? Ich meine mich erinnern zu können, wenn der Explorer in Verzeichnisse wechselt, die mit vielen Files belegt sind braucht der auch seine Zeit.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
nö - keine Sorge!
Jimmy, Directory macht leider keinen Unterschied zwischen acht "?" und einem "*"! Es wäre wahrscheinlich besser, wenn Du das erste und achte Zeichen mit angeben würdest in der Suchmaske - wobei ich mal vermute, das dann dazwischen die sechs "?" auch unberücksichtigt bleiben (im Sinne von: genau sechs Zeichen)...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Martin Altmann hat geschrieben:Directory macht leider keinen Unterschied zwischen acht "?" und einem "*"
Hallo Martin,

das stimmt so nicht, wenn die Dateien länger als 8 Buchstaben sind :wink:

Unter Win2000ff gilt:

A* alle Dateien und Verzeichnisse, egal ob mit oder ohne Endung.
A?????? alles was bis 7 Zeichen lang ist, egal ob mit oder ohne Endung.
A*. alles OHNE Endung ;-)

Ich vermute, dass der Rückgabewert auch vom Betriebssystem abhängt, da Xbase++ die Anfrage sicher nur durchroutet.
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hubert,
sorry, habe mich unklar ausgedrückt!
Ich wollte eigentlich darauf hinaus, dass ich nicht sagen kann, der Dateiname muß acht Zeichen lang sein - dass es bei längeren einen Unterschied gibt, ist schon klar :D

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

einfach aber mit der Zeit langwierig wäre das durchzählen.

Code: Alles auswählen

    for x := 1 to 999999
         cFile:= "AB"+strzero(x,6)+"A"
         if ! FExists(cFile)
            exit
         endif
    next
also müsste man einen einigermaßen zufälligen Anfangswert haben:

Code: Alles auswählen


    nStart := int(seconds()*10) // Max Seconds 86400 * 10 -> 6  Stellen

    for x := nStart to 999999
         cFile:= "AB"+strzero(x,6)+"A"
         if ! FExists(cFile)
            exit
         endif
    next
Das verkürzt natürlich den Zahlenraum.
Die 'zufälligen' Dateien sollten also regelmäßig gelöscht werden.
Gruß
Hubert
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hi Jimmy,
falls Du Besitzer der xBase-Tools bist, würde sich die Funktion "TempFile()" anbieten. Diese erzeugt einen unique Dateinamen.

Ansonsten würde ich einen File-Namen Val(DtoS) + seconds() ohne Nachkommastellen bilden und prüfen, ob eine Datei mit diesem Namen schon im Zielverzeichnis vorhanden ist.

Seconds() kann maximal den Wert von 86399.99 annehmen, umgewandelt zu 8639999.

Val(Systemdatum) ergibt 20071605. Beide Werte addiert ergeben niemals (außer in ganz, ganz ferner Zukunft) nicht mehr als 8 Ziffern. Solange der Anwender das Systemdatum nicht zurückstellt und zufällig zur selben Zeit und Millisekunde (sehr unwahrscheinlich) die Funktion ausführt, sollte dieser Ansatz ziemlich "robust" sein

Auf Basis dieses Ansatzes mal eine Funktion aus der Hüfte:

Code: Alles auswählen

Func UniqueFileName( cDir, cExtention)
Local nSec := Val( StrTran( ltrim(Str( Seconds())),".",""))
Local nDay := Val(Dtos( date() ))
Local cFile

cDir       := IIF( cDir == NIL, "", cDir)
cExtention := IIF( cExtention == NIL, ".TMP", "." + cExtention)

if ! empty( cDir )
   IF SubStr( cDir, len( cDir),1) <> "\"
       cDir := cDir + "\"
   endif
endif

cFile := cDir + Str(nDay + nSec,8,0) + cExtention

If  ! File( cFile )
  Return ( cFile )
endif
Return ( "")
Viele Grüße,
Olaf
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Ach ja: Die Informationen für die Code-Page könntest Du ja auch in der Extention unterbringen.
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hi Jimmy,
ich habe gerade gesehen, dass meine Lösung nur teilweise Dein Problem löst. Allerdings kann dem abgeholfen werden.

Mit Einsatz der xBase Tool-Funktion Mantissa() (zur Basis 2, das entspricht eine normalisierte Mantisse) kann ein 8 stelliger Wert auf 6 Stellen umgewandelt werden, indem über die Mantissen-Funktion die Nachkommastellen zur Bildung eines eindeutigen 6-stelligen Dateinamens genutzt wird. Für eine normalisierte Mantisse liegt der Vorkommawert immer zwischen >=1 und <=2. Die Vorkommastelle wird einfach weggelassen.

Die Funktion sieht dann so aus:

Code: Alles auswählen

Func UniqueFileName( cDir, cExtention, cFirstChar, cLastChar)
Local nSec := Val( StrTran( ltrim(Str( Seconds())),".",""))
Local nDay := Val(Dtos( Date()))
Local cFile
Local cTemp

cDir       := IIF( cDir == NIL, "", cDir)
cExtention := IIF( cExtention == NIL, ".TMP", "." + cExtention)

if ! empty( cDir )
   IF SubStr( cDir, len( cDir),1) <> "\"
       cDir := cDir + "\"
   endif
endif

cTemp := Strtran(Padr(Substr(ltrim(Str( Mantissa( nDay + nSec ) )),3),6)," ", "0")

cFile := cDir + cFirstChar + cTemp + cLastChar + cExtention

If  ! File( cFile )
  Return ( cFile )
endif
Return ( "")
Viele Grüße,
Olaf
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12910
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,

erstmal danke für euer Vorschläge. Ich muss die erst ausprobieren
bevor ich was dazu sagen kann.

gruss by OHR
Jimmy
Antworten