![]() |
Re: Eigene Funktion erstellen
Zitat:
Delphi-Quellcode:
und eigentlich hat die etwas kürzere Funktion von vorhin ihre Arbeit doch auch erfüllt :gruebel:
const
liste = array [0..2] of replace = ( (was='ö';durch='ö'), (was='ü';durch='uuml;'), (was='ä';durch='auml;') ); und wieso deklarierst du extra eine Konstante res anstatt dierekt auf result zuzugreifen? und die funktion einmalallesbitte hat nichts in der Klasse form1 zu suchen. In Form1 deklarierst du nur Funktionen, die dierekt auf die Elemente der Form zugreifen ("Methoden"). und verwende bitte sprechende Bezeichner ;) einmalallesbitte ist nicht besonders aussagekräftig. Andere Funktionen sollten nicht Bestandteil einer Klasse sein, sondern im Optimalfall sogar in einer eigenen Unit deklariert werden. so:
Delphi-Quellcode:
unit htmltools; interface type replace = record was, durch : string; end; const replaces = array [0..2] of replace = ( (was='ö';durch='ö'), (was='ü';durch='uuml;'), (was='ä';durch='auml;') ); function htmlreplace(text:string):string; implementation function htmlreplace(text:string):string; var i:integer; begin result := text; for i in replaces do result := StringReplace(res, replaces[i].was, replaces[i].durch, [rfReplaceAll]); end; |
Re: Eigene Funktion erstellen
:shock:
Nunja... mit Arrays habe ich mich/wir noch nicht beschäftigt. Solte ich vll. mal machen... scheint ein großes Benutzungpotenzial zu haben. Also ich habe das jetzt wie folgt gelöst:
Delphi-Quellcode:
Also wenn ihr wollt lad ich auch mal den gesamten Datenkram hoch. Ist jedoch mit Delphi 7 geschrieben worden... daher weis ich nicht wie so die Kopatibilität ist ;)
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type TForm1 = class(TForm) MText: TMemo; Mhtml: TMemo; SpeedButton2: TSpeedButton; SpeedButton3: TSpeedButton; ETitel: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; OpenD: TOpenDialog; SaveD: TSaveDialog; SpeedButton1: TSpeedButton; procedure SpeedButton3Click(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); procedure SpeedButton2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; Satz: String; implementation {$R *.dfm} function konvert(Text:string):string; var laenge, i, Buchstabe :Integer ; begin laenge:= Length(Text); result:='' ; For i:= 1 To laenge Do begin Buchstabe:= ord(Text[i]); Case Buchstabe of 228: result:= result + 'ä' ; 196: result:= result + 'Ä' ; 246: result:= result + 'ö' ; 214: result:= result + 'Ö' ; 252: result:= result + 'ü' ; 220: result:= result + 'Ü' ; 223: result:= result + 'ß' ; 13: result:= result + chr(13) + chr(10) + '<br' ; 10: result:= result + '>' + chr(13) + chr(10); Else result:= result + chr(Buchstabe); //Result muss verwendet werden, da sonst kein Endwert für die Funktion exestiert end; end; end; procedure TForm1.SpeedButton3Click(Sender: TObject); var Titel, Text: String; begin Text:= konvert(MText.Text); Titel:= konvert(ETitel.Text); MHTML.Clear ; MHTML.Lines.Add('<html>'); MHTML.Lines.Add('<head>'); MHTML.Lines.Add('<title>' + Titel + '</title>'); MHTML.Lines.Add('</head>'); MHTML.Lines.Add('<body>'); MHTML.Lines.Add( Text ) ; MHTML.Lines.Add('</body>'); MHTML.Lines.Add('</html>'); end; procedure TForm1.SpeedButton1Click(Sender: TObject); begin OpenD.Filename:='*.txt'; OpenD.Filter:='Textdatei(*txt)|*.txt'; if OpenD.Execute Then MText.Lines.LoadFromFile(OpenD.Filename); end; procedure TForm1.SpeedButton2Click(Sender: TObject); begin SaveD.FileName:='*.html'; SaveD.Filter:='HTML-Dateien(*html)'; If SaveD.Execute then MHTML.Lines.SaveToFile(SaveD.FileName); end; end. mfg Cya |
Re: Eigene Funktion erstellen
also:
@ res != result wenn man nested functions in delphi benutzt bekommt man teilweise probleme, da in einem nested scope delphi nicht ziwschen result der beiden funktionen unterscheiden kann (ist erfahrungswert)
Delphi-Quellcode:
Da bekommt man die tollsten Ergebnisse...
function func01(x : Integer) : Integer;
function inner(z : Integer) : Integer; begin result := z + 5; end; begin result := inner(x) + inner(x) + inner(x); end; Je nach delphi version sogar unterschiedlich! ^^ ausßerdem wenn man in einer funktion mit exit aussteigt, kann es dazu führen, dass man ein teilergebnis in result hat, das weiter verarbeitet wird. (so was bekommt man auch gut hin, wenn thread A abbricht mit einer exception 'Cannot draw to Canvas' was nicht zwingend das programm terminiert und dann Thread B damit weiter rechnet; Gehabt bei einem RS232-Buffer bei einer Ansteuersoftware) @sprechende Funktionen namen: An sich gebe ich dir recht. Aber 1. sollte hier eigentlich nur das prinzip im fordergrund stehen und nicht der saubere und beste name. Für mich war kreterium, dass er sich von den restelichen methoden durch einen markanten namen abhebt. Somit habe ich absichtlich eine etwas flapsigere form genommen. Warum keine globale funktion? In der Unit wird ein Objekt definiert!? Dann ist es auch eine methode und keine funktion. Globale funktionen haben imho nicht in einer "klasse" zu suchen. Wenn man statische methoden will kann man sich eine "statische unit" basteln in der alles gesammlet wird. Ordentlich ist es auf jeden fall die methode an die instanz der klasse zu binden, da man hier sicher sein kann, dass nicht so ein speicher chaos entsteht. auch gerade wenn er versucht von der methode auf globale variablen zu zu greifen, kann dass bei globalen funktionen ein Problem werden. Das sind ganz normale sachen wenn man Sauber OOP coded So und zum schluss man das Konstante Array: Meinst du echt das erhört die lesbarkeit? Klar wenn man das ordentlich macht legt man sich ne kleine ini-datei an und liesst das dort herraus. Wenn man aber das ganze array im code hat... und dann nicht nur 3 stk. sondern mal so 20stk... Viel spass beim Fehlersuchen, wenn du dich vertippt hast ^^ Dann leg ich mir das lieber in meherer zeilen, was für jedemanden, der sich gerade erst einarbeitet auch sehr viel einfacher zu lesen ist, so dass man den code wenigstens noch debuggen kann und eindeutige nicht all zu kryptische Fehlermeldungen erhält --- Corelgott ps.: Ach und btw. das was du da scheibst: Zitat:
(* ok vielleicht etwas pedantisch ^^ *) |
Re: Eigene Funktion erstellen
@ deine funktion
Sieht doch nett aus, solange die das tut, wass die soll ^^ Aber wie gesagt könntest dir nent teil mit der Funktion StringReplace abnehmen.. einfach mal in der Delphihilfe schauen Ach und @ array: du nutzt da schon etwas, was sich genau so ansprechen lässt ^^ for ... length(Text) do ... Text[i]; ^^ cya Corelgott |
Re: Eigene Funktion erstellen
Moin Corelgott,
Zitat:
Wenn ich Result erst einmal initialisiere (z.B. auf FEHLER), dann die eigentliche Funktion laufen lasse (incl. eventueller Abbrüche/Exit), und erst am Schluss Result mit dem, dann korrekten, Ergebnis fülle, habe ich das Problem umgangen. Das setzt natürlich voraus, dass man Result, ausser an den genannten Stellen, nicht benutzt. Zitat:
|
Re: Eigene Funktion erstellen
hmm in Bezug auf das & zeichen gebe ich dir recht...
das müsste man gesondert behandeln... bzw. einmal vorweg... D.h. als erstes in der Liste StringReplace hat aber den Vorteil, dass man nicht jedes Zeichen einzeln durchgehen muss... Aber wie dem auch sei: Hauptsache es geht! Und die selbstgebaute Lösung, ist im jeden Fall die bessere, da er sie ja versteht! Und das ist sehr viel mehr Wert als eine Blackbox... Mal auf das exit = "Programm fehler bezogen" Wenn man das so sehen will, dass man dort einen Fehler hat... Ist ok... wäre dann ein Logik / Konzept Fehler Aber ich persönlich finde es dennoch unschön, "im Ergebnis" herrum zu rechnen. Ich bin durchaus ein Freund des C-Syntaxs und benutze in der Regel "result" sehr ähnlich zu "return". (Wohl wissentlich dass das eine ein Sprachkonstrukt ist und das andere eine "spimple" Varaible, an der ein bissel Compiler-Magic hängt) Ich kann mich da auch erinnern, dass man in C eigentlich ordentlicher Weise nur ein "return" nimmt! also NICHT
Code:
sondern:
if (foobar)
return true; else return false;
Code:
(* ok ok, nicht gerade das perfekte bsp. "return foobar;" wäre schlanker; aber es zeigt was ich meine *)
if (foobar)
res = true; else res = false; return res; Aber ich glaube mal, dass dies reihne Geschmackssage ist. Ich behaupte aber, dass es die Lesbarkeit des Codes erhöht... cya Corelgott |
Re: Eigene Funktion erstellen
Moin -lx-,
sollte Dir jetzt auffallen, dass die Performance nicht sonderlich ist, kannst Du die Konvertierung auch zweistufig machen. Durch das ständige anfügen von Zeichen an einen String wird oft auch ständig neuer Speicher angefordert, und das bisherige Ergebnis umkopiert. Wenn Du erst die erforderliche Länge ermittelst, dann einen entsprechend grossen Buffer für das Ergebnis einrichtest, und dann erst das Ergebnis ermittelst kannst Du (hängt auch vom jeweilige Umfang des Textes ab), die Geschwindigkeit erhöhen. Das nur als Info am Rande, mit einem kleinen Beispiel, da ich mir vorstellen kann, dass es für den Anfang sonst schwer nachvollziehbar ist:
Delphi-Quellcode:
Das nur als Beispiel, denn mit festen Werten sollte man tunlichst nicht arbeiten (z.B. 'ä', 'ä' usw.) damit man diese Daten dann ein einer zentralen Stelle ändern kann, und um Tippfehler zu vermeiden.
function Konvert(const AsValue : string) : string;
// AsValue statt Text, da dies als häufig verwendeter Name // für eine Eigenschaft zu Verwechslungen führen kann var sResult : string; iCount : integer; iIndex : integer; pPos : PChar; begin Result := ''; if AsValue = '' then exit; iCount := 0; for iIndex := 1 to length(AsValue) do begin case AsValue[iIndex] of 'ä' : inc(iCount,6); // um 6 erhöhen, da ä sechs Zeichen lang ist 'Ä' : inc(iCount,6); // usw. else inc(iCount); // wenn es kein Sonderzeichen ist, wird es direkt übernommen, also nur +1 end; end; SetLength(sResult,iCount+1); // Es werden iCount Zeichen benötigt // +1, da die im Folgende benutzte Funktion // am Ende noch eine #00 hinzufügt pPos := @sResult[1]; for iIndex := 1 to length(AsValue) do begin case AsValue[iIndex] of 'ä' : pPos := StrLCopy(pPos,PChar('ä'),6)+6; // +6, um auf die nächst Position zu kommen 'Ä' : pPos := StrLCopy(pPos,PChar('Ä'),6)+6; else pPos := StrLCopy(pPos,@AsValue[iIndex],1)+1; end; end; Result := sResult; end; Man könnte so die Konfiguration für die Konvertierung auch in einer Konfigurationsdatei halten, und kann so die Umwandlung ergänzen/ändern, ohne das Programm anfassen zu müssen. Wie gesagt, dass nur als zusätzliche Info, die "einfache" Variante sollte auch erst einmal genügen. Nur solltest Du eben nicht direkt mit Result arbeiten, sondern einer Hilfsvariablen, die dann das Ergebnis aufnimmt, und zum Schluss an Result zugewiesen wird. @Corelgott, Zitat:
Damit muss man den Komfort dann eben "bezahlen". Zitat:
Zugegeben, die Verwendung von Exit widerspricht dem Prinzip, dass eine Funktion nur einen Ein- und einen Ausgang haben soll, es kann aber IMHO dennoch die Lesbarkeit verbessern. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:57 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