Autor |
Beitrag |
Markus696
Hält's aus hier
Beiträge: 7
|
Verfasst: Di 25.03.14 09:46
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function kill_ctrlchars(exp : string):string; var i, _num : integer ; _array : Tarraych ; begin
result := '' ;
setlength( _array, length( exp ) ) ;
for i := 1 to length( exp ) do _array[ i-1 ] := exp[ i ] ;
for i := 0 to length( _array ) do _num := ord( _array[ i ] ) ; if ( _num <> ( 13 or 10 ) ) then result := result + _array[ i ] ;
end; |
Diese Funktion soll eigentlich einen Eingabestring dahingehend verarbeiten, dass sie ihn zunächst in die einzelnen Zeichen zerlegt und in einem dynamischen Array of char ablegt. Dann werden die einzelnen Zeichen betrachtet, und alle die dem numerischen Wert 10 oder 13 in ASCII entsprechen gelöscht. Sonst ver- bzw. entschlüsselt mein Programm manchmal noch diese ungewollten Steuerzeichen, und an der eigentlichen Nachricht hängen dann aufeinmal 2 sinnlose Zeichen hinten dran.  Deshalb möchte ich diese Funktion laufen lassen. Bloß leider bekomme ich in der markierten Zeile immer einen Error. Leider sehe ich nicht, was ich falsch gemacht habe. Hat jemand eine Idee?
Liebe Grüße
Moderiert von Martok: Code- durch Delphi-Tags ersetzt
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Di 25.03.14 10:00
Hallo,
Length liefert bei dynamischen Arrays die Anzahl der Elemente. Da das Array mit dem Index 0 beginnt, gibt es kein Element _array[length(_array)). Richtig wäre
Delphi-Quelltext 1: 2: 3: 4:
| ... for i := 0 to length( _array )-1 do _num := ord( _array[ i ] ) ; ... |
Beste Grüße
Mathematiker
Moderiert von Martok: Code- durch Delphi-Tags ersetzt
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 25.03.14 10:22
Markus696 hat folgendes geschrieben : | Quelltext 1:
| function kill_ctrlchars | |
Weshalb so umständlich? Dafür gibt's doch die String-Replace-Funktionen, einmal für Ansistrings und einmal für Unicode-Strings.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| function kill_ctrlchars(Original : String) : String; Var Ergebnis : String; begin Ergebnis := StringReplace(Original,#13,'',[rfReplaceAll]); Result := StringReplace(Ergebnis,#10,'',[rfReplaceAll]); end; |
Hinweis: Verwende zum Kennzeichnen von Delphi-Code besser delphi und /delphi in eckigen Klammern statt code und /code.
Anmerkung: Deine Überschrift hat mit dem Thema nichts zu tun. Hier wäre besser geeignet: "Zeichen in String ersetzen"
|
|
Blup
      
Beiträge: 174
Erhaltene Danke: 43
|
Verfasst: Di 25.03.14 10:44
Für Parameter vom Typ String, Array, Record, Interface sollte man immer den Art der Übergabe angeben, im Optimalfall 'const'.
Damit kann der Compiler einfacheren und schnelleren Code erzeugen.
Bei 0-basierenden Arrays ist bei High() Schluss, nicht bei Length() (wurde schon gesagt).
Das 'or' wird in deiner Notation als Bitoperator verstanden, die einzelnen Bits der Zahlen werden miteinander verknüpft:
Quelltext 1: 2:
| (13 or 10) = 15 %1101 or %1010 = %1111 |
Nach deiner Beschreibung willst du aber nicht mit 15 vergleichen, sondern mit den Elementen einer Menge:
Delphi-Quelltext 1:
| if not (_num in (13, 10)) then |
Das Array kannst du einsparen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| function kill_ctrlchars(const exp: String): String; var i: integer; begin result := '' ; for i := 1 to length(exp) do if not (ord(exp[i]) in (13, 10)) then result := result + exp[i]; end; |
Zuletzt bearbeitet von Blup am Di 25.03.14 18:45, insgesamt 1-mal bearbeitet
|
|
Nersgatt
      
Beiträge: 1581
Erhaltene Danke: 279
Delphi 10 Seattle Prof.
|
Verfasst: Di 25.03.14 10:54
Blup hat folgendes geschrieben : | Für Parameter vom Typ String, Array, Record, Interface sollte man immer den Art der Übergabe angeben, im Optimalfall 'const'. |
Wenn man nichts angibt, werden die Parameter doch standardmäßig als Const übergeben. Dann kann man sich die Angabe sparen.
_________________ Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
|
|
Blup
      
Beiträge: 174
Erhaltene Danke: 43
|
Verfasst: Di 25.03.14 11:08
|
|
Gammatester
      
Beiträge: 328
Erhaltene Danke: 101
|
Verfasst: Di 25.03.14 11:32
Auch man nicht die mitgelieferten Funktionen verwenden will, verstehe ich nicht, warum man so umständlich über dynamische Arrays und Ordinalzahlen der Zeichen geht (und sich da die genannten Probleme mit Indexüberschreitung und 13 or 10 = 15 einhandelt):
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function kill_ctrlchars(const exp: string): string; var i: integer; c: char; begin result := ''; for i:=1 to length(exp) do begin c := exp[i]; if (c<>#10) and (c<>#13) then result := result + c; end; end; |
Zuletzt bearbeitet von Gammatester am Di 25.03.14 14:47, insgesamt 1-mal bearbeitet
|
|
IhopeonlyReader
      
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Di 25.03.14 15:26
Perlsau hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| function kill_ctrlchars(Original : String) : String; Var Ergebnis : String; begin Ergebnis := StringReplace(Original,#13,'',[rfReplaceAll]); Result := StringReplace(Ergebnis,#10,'',[rfReplaceAll]); end; |
|
ich mache das mal am Beispiel der besten vorgeschlagenen Lösungen fest:
ich würde da allerdings aufpassen, natürlich macht das genau das, was der Threadersteller haben will...
Aber wenn ich z.B.
Zitat: | Guten Tag,
wie geht es euch? |
durch die funktion laufen lasse, fehlt ein leerzeichen!, für solch einfache Sätze mag das kein problem sein, aber ich denke man sollte vorher getrennte wörter weiterhin trennen...
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| function kill_ctrlchars(Original : String) : String; begin Result := StringReplace(Original, #13, ' ', [rfReplaceAll or rfIgnoreCase]); Result := StringReplace(Result, #10, ' ', [rfReplaceAll or rfIgnoreCase]); Result := StringReplace(Result, ' ', ' ', [rfReplaceAll or rfIgnoreCase]); end; |
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 25.03.14 16:04
Das Leerzeichen hab ich natürlich nicht berücksichtigt, weil ich davon ausgegangen bin, daß der TE lediglich ein Beispiel benötigt, wie er am einfachsten Zeichen ersetzt und daher selbst drauf kommen würde, wenn ihm irgendwo ein Leerzeichen fehlt. Doch wenn schon, dann so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| function kill_ctrlchars(Original : String) : String; Const S = #32;
begin Result := StringReplace(Original,#13 + #10,S,[rfReplaceAll]); Result := StringReplace(Result ,#10 + #13,S,[rfReplaceAll]); Result := StringReplace(Result ,#10, S,[rfReplaceAll]); Result := StringReplace(Result ,#13, S,[rfReplaceAll]); end; |
Also erst nach der Anordnung #13 + #10 suchen, weil die in dieser Kombination häufig zum Einsatz kommt, danach nochmal einzeln abklappern, man weiß ja nie.
Das Flag rfIgnoreCase benötigt man nicht wirklich, da es sich hier nicht entsprechende Zeichen handelt.
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Di 25.03.14 22:03
Da hätte ich auch noch einen (der Einfachheit halber ohne Pointer-Arithmetik):
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| function StripLinebreaks(const Src: string): string; const CR = #13; LF = #10; var i, ResultLength: integer; begin SetLength(Result, Length(Src)); ResultLength := 0; for i := 1 to Length(Src) do if not CharInSet(Src[i], [CR, LF]) then if not (Src[i] in [CR, LF]) then begin inc(ResultLength); Result[ResultLength] := Src[i]; end; SetLength(Result, ResultLength); end; |
|
|
|