AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Wie baut man sowas wie writeln/sprintf selbst ?
Thema durchsuchen
Ansicht
Themen-Optionen

Wie baut man sowas wie writeln/sprintf selbst ?

Ein Thema von flash2009 · begonnen am 25. Dez 2008 · letzter Beitrag vom 27. Dez 2008
Antwort Antwort
Seite 1 von 3  1 23      
flash2009

Registriert seit: 15. Dez 2008
11 Beiträge
 
#1

Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 04:25
Hey
ich wollte sprintf hooken
das ist vom aussehen ähnlich wie printf oder writln
es wird eine umbestimmte anzahl von parametern übergeben, die man nur ermitteln kann wenn man im string oder pchar der übergeben wird die platzhaltern (%d ..) zählt.

Im Intenet und überall find ich nur so Standart function oder procedure mit ner festen Anzahl an Parametern , wie deklariert man sowas dynamisches.
function meine (var p1,p2... pn):boolean; << sowas

Ansonsten könnt ich da noch mit Inline asm den krempel vom stack nehmen aber das wäre ja murks.

gruß und frohe Weihnachten flash
  Mit Zitat antworten Zitat
WS1976
(Gast)

n/a Beiträge
 
#2

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 08:02
Hallo,

aus deinem Beitrag ist zwar nicht genau herauszufinden was du willst aber ich interpretiers mal so:
Du suchst eine Möglichkeit die Parameterübergabe in Delphi dynamisch zu machen.
 Procedure Test(a,b:integer;c:boolean=true); a und b sind hier feste Parameter c kannst du gegebenenfalls weglassen wird dann automatisch auf true gesetzt.

Frohe Weihnacht und einen guten Rutsch wünsche ich dir und allen DP'lern
Rainer

[edit=Sharky]Dalphi-Tag korrigiert. Mfg, Sharky[/edit]
  Mit Zitat antworten Zitat
PMM

Registriert seit: 17. Feb 2005
101 Beiträge
 
#3

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 08:49
Schau die mal die Function "format" an. Die macht so was ähnliches.
Evtl ist ja:
Delphi-Quellcode:
 
writeln(format(frmstr,args));
schon das was du haben willst.
Frohes Fest
PMM
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 09:33
In Delphi kann man keine beliebige Anzahl von Parametern deklarieren. In C(++) und C# geht das, weil hier die Aufrufkonventionen anders sind und die Sprache zudem spezielle syntaktische Elemente bereit hält.

WS1976 hat schon angedeutet, wie man ein sprintf in Delphi theoretisch deklarieren könnte. Leider benötigst Du hier allgemeingültige Typen (Variants) und damit funktioniert das nicht. Die Lösung liegt im etwas merkwürdigen Konstrukt 'Array Of Const', mit dem man heterogene Daten in Form eines dynamischen Arrays übergeben kann. Allerdings ist der Zugriff auf einzelne Elemente dieses Arrays nicht gerade trivial.

Die Lösung von PMM ist also die Richtige:
Delphi-Quellcode:
Procedure PrintF (Const FmtStr : String; Args : Array Of Const);
Begin
  Writeln (Format(FmtStr, Args))
End;
Und der Aufruf:
PrintF('Hallo %s, Frohe Weihnacht und einen guten Rutsch ins Jahr %d',['flash2009',2009]);
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#5

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 13:32
Zitat von alzaimar:
Die Lösung liegt im etwas merkwürdigen Konstrukt 'Array Of Const', mit dem man heterogene Daten in Form eines dynamischen Arrays übergeben kann. Allerdings ist der Zugriff auf einzelne Elemente dieses Arrays nicht gerade trivial.
Kannst du das mit dem Array of Const nochmal genauer ausformulieren oder einen Link posten, der es erklärt? Hilft sowas eine Funktion die immer das selbe macht nicht für alle möglichen unsigned/signed int Typen überladen zu müssen und so unnötig viel Code zu linken? Die Offsets im Arrays ggf. selbst zu berechnen wäre, wenn man an die Typengröße ran kommt auch kein Problem.



[OFFTOPIC]Hier und heute stellen sich die Fragen, und ich glaube, Sie stimmen mit mir überein[...]
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 13:35
Man muss den Array im Aufruf der Funktion dynamisch erstellen (z.B. VarArrayOf())
Markus Kinzler
  Mit Zitat antworten Zitat
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#7

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 13:56
Vielleicht ganz nützlicher Link: http://rvelthuis.de/articles/articles-openarr.html
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 15:20
Zitat von mkinzler:
Man muss den Array im Aufruf der Funktion dynamisch erstellen (z.B. VarArrayOf())
Äh. Nein? Eine Routine mit einem 'Array Of Const'-Parameter kann man so aufrufen, wie bei der Format-Funktion. Nur eben der Zugriff ist nicht trivial. Warte mal, ich kram mal in meinem Archiv... *kram* *such*
Delphi-Quellcode:
Function ElementOfConst(aIndex: Integer; aArray: Array Of Const): Variant;
Begin
  With aArray[aIndex] Do
    Case VType Of
      vtInteger:
        Result := VInteger;
      vtBoolean:
        Result := vBoolean;
      vtChar:
        Result := VChar;
      vtExtended:
        Result := vExtended^;
      vtString:
        Result := VString^;
      vtPChar:
        Result := StrPas(VPChar);
      vtObject:
        Result := VObject.ClassName;
      vtClass:
        Result := VClass.ClassName;
      vtAnsiString:
        Result := String(VAnsiString);
      vtCurrency:
        Result := VCurrency^;
      vtVariant:
        Result := VVariant^;
      vtInt64:
        Result := VInt64^;
    End;
End;
So kann ich auf die einzelnen Elemente eines 'Array Of Const' zugreifen, was eigentlich ein Array Of TVarRec ist (ähnlich aber nicht identisch mit TVarData, also einem Variant).

Ich kann dann also sowas spektakuläres bauen, wie z.B.:
Delphi-Quellcode:
Procedure ListItems (aArgs : Array Of Const);
Var
  i : Integer;

Begin
  For i:=0 to High (aArgs) do
    Writeln (ElementOfConst(i,aArgs));
End;
...
ListItems (['Foo','Bar',1.2, 3.456, 7]);
Ob man das jemals benötigt, steht auf einem anderen Blatt.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#9

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 15:53
Also ich hab auch mal ein bischen rumprobiert und ein (sinnloses) Beispiel gebastelt. Allerdings bietet die Methode in meinen Augen grade für mich mehr Nachteile als überladen:

1. Man kann keine normalen Arrays mehr übergeben, mag sein dass man das hinbiegen kann, indem man erst irgendwie nach array of TVarRec umwandelt.

2. Der Compiler genieriert beim Aufruf intern erstmal ein array of TVarRec, das verusacht wahrscheinlich grade bei großen Arrays erstmal relativ viel Aufwand, außerdem wird für jedes Element der Typ mitgespeichert (was wenn mans kombinieren möchte natürlich nötig ist), so dass die Größe jedes Elements damit auf 8 Byte anwächst (da das ganze außerdem intern ne Union ist).

3. Wenn ich den Link, den ich gepostet hab, richtig versteh, ist der Zugriff über die Pointer in dem TVarRec zur Modifikation der Orginaldaten (also by reference) problematisch und man muss die Daten erst kopieren, weil die Daten, auf die man zugreift, nach dem Funktionsaufruf nicht mehr existieren, da sie nur temporär erzeugt und auf den Stack gelegt werden. Eine Möglichkeit scheint hier zu sein in der Funktion Heap-Speicher zu reservieren und einen Zeiger darauf zurückzugeben, das verursacht aber auch wieder Aufwand.

Sieht also, da ichs für verschiedene Sortierfunktionen (die natürlich schnell sein sollen) brauch, für mich spontan nicht so geeignet aus, ich werd also entweder auf procedure SortierWas(Data: Pointer; Count: Integer; ElementSize: Integer) umsteigen müssen, was aber den Zugriff auf einzelne Elemente recht schwer macht (man müsste die Size abfragen und je nachdem den entsprechenden Pointer casten und dereferenzieren, um die Werte vergleichen zu können, damit verliert man aber Zeit, wenn es um große Arrays geht und braucht immer noch getrennte Funktionen für signed und unsigned), oder ich bleib einfach dabei alles zu überladen, was ich wohl mach. (Sorry, das war ein wenig Offtopic, ich weiß)
Angehängte Dateien
Dateityp: dpr arrayofconst_148.dpr (1,5 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von inherited
inherited

Registriert seit: 19. Dez 2005
Ort: Rosdorf
2.022 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Wie baut man sowas wie writeln/sprintf selbst ?

  Alt 25. Dez 2008, 18:41
Ich hab mal mit solchen Cost-Arrays eine Klasse für MySQL-Zugriffe geschrieben. Damit konnte man dann recht bequem Inserten und sowas
Nikolai Wyderka

SWIM SWIM HUNGRY!
Neuer Blog: hier!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:58 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz