Autor Beitrag
Markus696
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Di 25.03.14 09:46 
ausblenden 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 ] ) ;           //Fehlermeldung Internal Error SIGSEGV
    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 user profile iconMartok: Code- durch Delphi-Tags ersetzt
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1448

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: 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
ausblenden Delphi-Quelltext
1:
2:
3:
4:
...
  for i := 0 to length( _array )-1 do
    _num := ord( _array[ i ] ) ;        
...

Beste Grüße
Mathematiker

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 25.03.14 10:22 
user profile iconMarkus696 hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden 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.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 174
Erhaltene Danke: 43



BeitragVerfasst: 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:
ausblenden 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:
ausblenden Delphi-Quelltext
1:
if not (_num in (1310)) then					


Das Array kannst du einsparen:
ausblenden 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 (1310)) then
      result := result + exp[i];
end;


Zuletzt bearbeitet von Blup am Di 25.03.14 18:45, insgesamt 1-mal bearbeitet
Nersgatt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Di 25.03.14 10:54 
user profile iconBlup hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 174
Erhaltene Danke: 43



BeitragVerfasst: Di 25.03.14 11:08 
user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconBlup hat folgendes geschrieben Zum zitierten Posting springen:
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.

Nein, das ist nicht richtig.
Bei diesen Typen werden Kopien der Orginaldaten angelegt oder zumindest die Referenzzähler hochgesetzt.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: 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):
ausblenden 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<>#10and (c<>#13then result := result + c;
  end;
end;


Zuletzt bearbeitet von Gammatester am Di 25.03.14 14:47, insgesamt 1-mal bearbeitet
IhopeonlyReader
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Di 25.03.14 15:26 
user profile iconPerlsau hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden 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...
ausblenden 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]); {bin mir nicht sicher ob 3x#1 auch durch 1x#1 ersetzt wird, müsste aber}
end;

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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:

ausblenden 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]); // ob man diese Zeile benötigt, darf bezweifelt werden, muß der TE selber entscheiden
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Di 25.03.14 22:03 
Da hätte ich auch noch einen (der Einfachheit halber ohne Pointer-Arithmetik):
ausblenden 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
    (* Delphi > 2007 *)
    if not CharInSet(Src[i], [CR, LF]) then
    (* ältere Versionen *)
    if not (Src[i] in [CR, LF]) then
      begin
        inc(ResultLength);
        Result[ResultLength] := Src[i];
      end;
  SetLength(Result, ResultLength);
end;