Entwickler-Ecke

Dateizugriff - Textdatei einlesen>TEil der Textdatei ersetzen?


playsta - Mo 02.02.09 15:26
Titel: Textdatei einlesen>TEil der Textdatei ersetzen?
Also ich habe das Problem das ich zu erst eine Textdatei einlesen muss .Diese soll dann vom Programm so bearbeitet werden das ein Teil dieser Textdatei durch die Eingabe die in einem Memo feld getätigt wurde ersetzt wird.
danke im vorraus;)


Delete - Mo 02.02.09 15:27

Und was ist Deine Frage? :gruebel:


playsta - Mo 02.02.09 15:30

Die Frage ist wie ich genau vorgehen kann und mit welchen Befehlen ich da am besten arbeiten kann..
Dabei zu berücksichtigen ist das meine Delphikenntnisse wie man vllt merkt relativ begrenzt sind ;)


Delete - Mo 02.02.09 15:36

Dieser "Teil der Textdatei" ist aber fix (Zeilennummer)? Oder muss die Zeile anhand des Inhalts erst ermittelt werden? Mehr Infos bitte.


playsta - Mo 02.02.09 15:39

Also der Teil der Textdatei ist fix also man kann ihn über die Zeile angeben


Delete - Mo 02.02.09 15:45

Und wenn das Memo weniger Zeilen enthält als die Textdatei ab der genannten Zeile, sollen die restlichen Zeilen erhalten bleiben? Beispiel:
Datei

Quelltext
1:
2:
3:
4:
5:
Erste Zeile
Zweite Zeile
Dritte Zeile
Vierte Zeile
Fünfte Zeile

Memo

Quelltext
1:
2:
Neue Zweite Zeile
Neue Dritte Zeile

Was soll mit den Zeilen 4 und 5 in der Datei geschehen?


playsta - Mo 02.02.09 15:48

Ja die restlichen müssen erhalten bleiben .
Es soll also nur diese eine Zeile dann ersetzt werden .


jaenicke - Mo 02.02.09 16:15

Am einfachsten wird eine TStringList sein. Die erstellst du, dann lädst du die Datei mit LoadFromFile. Danach ersetzt du die Zeilen, speicherst die Datei wieder und entfernst die TStringList aus dem Speicher.

Ein kleiner Einstieg:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  i: Integer;
  FileContents: TStringList;
begin
  FileContents := TStringList.Create;

  FileContents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Datei.txt'); // Datei im selben Verzeichnis
  // ODER
  FileContents.LoadFromFile(OpenDialog1.FileName); // Im OpenDialog gewählte Datei

  for i := 0 to Memo1.Lines.Count - 1 do
    ShowMessage('Ersetzen: ' + FileContents[i + StartZeileInDerDatei]);

  FileContents.SaveToFile(...
  FileContents.Free;


playsta - Mo 02.02.09 16:59

Ok danke über zeile klappt, jetzt bräuchte ich das gleiche jedoch noch zeilenunabhängig, sodass man also die Zeilen nach dem Inhalt ermitteln muss.


Delete - Mo 02.02.09 17:13

Das ginge z.B. mit TStringlist.IndexOf (bei exakter Übereinstimmung).


playsta - Mo 02.02.09 17:53

ok.. und bei nicht exakter Übereinstimmung?


Delete - Mo 02.02.09 18:00

Dann müsstest Du in einer Schleife durchgehen und nach Übereinstimmungen suchen (z.B. mit der Pos-Funktion).


playsta - Mo 02.02.09 18:18

Ok ich versuch es mal aber weitere Tipps oder Vorschläge sind immer herzlich willkommen;)


jaenicke - Di 03.02.09 03:12

Du könntest auch direkt im gesamten Text danach suchen. Bei einer StringList FileContents wäre das FileContents.Text. Darin kannst du mit Pos auch direkt suchen.

Die Frage ist was du jetzt eigentlich genau machen willst. An einer durch einen enthaltenen Text bestimmten Stelle einen anderen Text einfügen?
Ist der gesuchte Text ein spezieller Platzhalter, der eindeutig in der Datei ist und komplett ersetzt werden soll z.B.?


playsta - Di 03.02.09 10:26

ja es ist wie ein platzhalter.
Um es mit einem Beispiel zu erklären könnte man es so sagen :
Wir ich habe ein formular zb. einen Fehlerprotokoll oder eine Meldung das die angewendedete Anwendung nicht länger ausgeführt werden kann .
Dann soll über ein Memofeld ein Text angegeben werden in den man zB. dann einen eigenen Kommentar dazu abgeben kann.


playsta - Di 03.02.09 11:19

Aber zwischendurch nochmal eine vllt ziemlich banale Frage.
Wie öffne ich die neu gespeicherte *.txt- datei dann das sie direkt nach dem einsetzen der neuenAngabe angeeigt wird?


jojo-sp - Di 03.02.09 11:35

Es besteht ja auch die Möglichkeit zwei Strings mit dem Levenshtein Verfahren zu vergleichen. Dann müssen die Zeilen nicht Wort für Wort übereinstimmen. Du musst dann die Datei bzw. Stringlist Zeilenweise abklappern und die beste Übereinstimmung ermitteln. Schau dir mal folgenden Link an:

http://www.delphipraxis.net/topic70118_levenshteindistanz.html&highlight=levenshteindistanz

MfG Johannes


jaenicke - Di 03.02.09 11:41

user profile iconplaysta hat folgendes geschrieben Zum zitierten Posting springen:
ja es ist wie ein platzhalter.
Dann kannst du mit Pos auf FileContents.Text angewendet die Position feststellen.

Der neue Inhalt ist dann FileContents.Text von Buchstabe 1 bis zu der Position - 1 plus dein Memo-Text plus FileContents.Text von Position + Länge des Platzhalters bis zum Ende. Das kannst du also mit zweimal Copy lösen.

user profile iconplaysta hat folgendes geschrieben Zum zitierten Posting springen:
Wie öffne ich die neu gespeicherte *.txt- datei dann das sie direkt nach dem einsetzen der neuenAngabe angeeigt wird?
Memo1.Lines.LoadFromFile


playsta - Di 03.02.09 12:02

Ok danke versuch ich es erst mal so mit FileContents.Text.:)
Falls ihr aber noch weitere Ideen in richtung Quelltext direkt habt hscreibtse ruhig;)


playsta - Di 03.02.09 12:15

Da ich blutiger Anfänger bin hab ich noch Probleme das irgendwie in Quelltext umzusetzen ,kann mir das jemand vllt in Quelltext oder zumindestens einen Teil davon in Quelltext darstellen damit ich zuminest wirklich weiß wie ich anfangen soll?


jaenicke - Di 03.02.09 14:55

Hast du denn verstanden was Pos und Copy machen? Wenn ja, dann sollte dir das reichen: (wenn nicht, dann probier das erstmal einzeln aus)

Delphi-Quelltext
1:
2:
3:
TextPos := Pos(...
FileContents.Text := Copy(FileContents.Text, 1, TextPos - 1) + MemoText
  + Copy(FileContents.Text, TextPos + TextLength, Length(FileContents.Text) - ...);
Viel fehlt ja nicht mehr, aber ich denke einmal du siehst wie mein letzter Post gemeint war. ;-)


playsta - Di 03.02.09 15:28

Ja also ich denke shcon das ich verstanden habe was pos und copy machen..auf jeden fall so ziemlich ;) naja trotzdem habe ich noch probleme mit deinem quelltext .
Es ist so ich habe vorher mit Delphi noch nie in diese 'Programmiergebieten' gearbeitet muss das jetzt 'quasi notgedrunegen' machen und bin deswegen völlig neue in diesen bereichen von delphi


jaenicke - Di 03.02.09 15:32

Vielleicht hilft das ja auch:

Quelltext
1:
2:
3:
4:
5:
6:
7:
x ist dein ursprünglicher Text, AAA der zu ersetzende Teil.

xxxxxxxxxxxxxxxxxxxAAAxxxxxxxxxxxx
<-     Copy1     ->   <-  Copy2 ->

Das Ergebnis soll dann sein:
Copy1 + Memo1.Text + Copy2
Das heißt mit den beiden Copy-Aufrufen kopierst du alles vor und nach dem zu ersetzenden Text, dazwischen setzt du noch den Inhalt des Memos.


Delete - Di 03.02.09 15:50

Sollte das nicht mit StringReplace einfacher gehen?


jaenicke - Di 03.02.09 16:11

Einfacher ja, aber es ist vermutlich langsamer.


playsta - Di 03.02.09 16:15

okdas mit copy und den ganzen sinn hab ich dann jetzt wenigstens schon mal verstanden jedoch setzt er bei meinem programm den text aus memo immer ganz an den anfang .. und nich da wo er hin soll auf'##content##'


Delete - Di 03.02.09 16:18

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Einfacher ja, aber es ist vermutlich langsamer.

Ja und? Das soll vermutlich ja nicht 50 mal pro Sekunde gemacht werden :mrgreen:


playsta - Di 03.02.09 16:45

So ich denke mal das Programm würde soweit laufen wenn ich wüsste was ich bei pos angeben muss? mir ist zwar so eig klar was sie macht aber ich weiß nicht wie man das angibt?


Delete - Di 03.02.09 17:12

Delphi 7-Hilfe hat folgendes geschrieben:

Delphi-Quelltext
1:
function Pos(Substr: string; S: string): Integer;                    


Beschreibung

In Delphi sucht Pos in dem String S nach dem Teil-String Substr. Die Parameter Substr und S sind String-Ausdrücke.

Wird der Teil-String gefunden, gibt Pos den Integer-Index des ersten Zeichens von Substr in S zurück. Die Groß/Kleinschreibung wird von Pos nicht berücksichtigt. Ist Substr nicht vorhanden, wird der Wert Null zurückgegeben.

Die Funktion PosEx entspricht Pos, hat aber eine umfangreichere Funktionalität und kann in C++ Code verwendet werden.


playsta - Di 03.02.09 17:21

ja in der Hilfe nahcshclagen hatte ich auch hscon gemacht;)
Nur irgendwie is die Erklärung für mich nicht grade shclüssig :D


GTA-Place - Di 03.02.09 17:37

Dann sag uns doch, was du daran nicht verstehst. Da steht doch, wie man die Funktion aufruft: Pos('ich''Wer bin ich?');


Delete - Di 03.02.09 17:38

Deine Rechtschreibung ist für mich auch nicht schlüssig, da sind etliche Bachstuben dervreht. Und so schwer ist Pos ja nun nicht, Du suchst im String S nach der Zeichenfolge substr. Die Funktion gibt Dir die erste Fundstelle zurück. Ist substr nicht in S enthalten, gibt sie 0 zurück.


playsta - Di 03.02.09 17:59

Die Frage ist hier , was ist was?
Also der String wäre bei mir dann die txt-datei oder vertuh ich mich da jetzt komplett ?
Und der Substring dann einfach das Wort was als Platzhalter dient oder??


jaenicke - Di 03.02.09 18:05

user profile iconplaysta hat folgendes geschrieben Zum zitierten Posting springen:
Also der String wäre bei mir dann die txt-datei oder vertuh ich mich da jetzt komplett ?
Das ist schon richtig, FileContents.Text ist das.

user profile iconplaysta hat folgendes geschrieben Zum zitierten Posting springen:
Und der Substring dann einfach das Wort was als Platzhalter dient oder??
Ja, genau.


playsta - Mi 04.02.09 10:28

Ja ok dann kann das Problem daran nicht liegen .
Jedoch macht das Programm immer noch nicht das was ich will.
Die Zeile die die ersetzt werden soll bleibt bis auf den ersten buchstaben und die erste zeile wird ersetzt.
Weiß jemand warum das so sein könnte?


Delete - Mi 04.02.09 10:33

Du machst einen Fehler in Zeile 23 :mrgreen: Im Ernst: was soll man ohne Code dazu sagen?


playsta - Mi 04.02.09 10:36

FileContents.Text := Copy(FileContents.Text, 1, TextPos - 1) + Memo1.Text
+ Copy(FileContents.Text, TextPos + TextLength, Length(FileContents.Text));

Hier fehlt noch was denk ich mal .


Delete - Mi 04.02.09 10:46

TextPos und TextLength stimmen aber? Lass Dir das doch einmal ausgeben.

Delphi-Quelltext
1:
ShowMessage(Copy(FileContents.Text, TextPos, TextLength));                    


playsta - Mi 04.02.09 10:51

Oh das kann schon mal nicht alles stimmen.
Er gibt mir aus: Memo1
ntent##


Delete - Mi 04.02.09 11:08

Dann wird der Denkfehler schon früher gemacht.


playsta - Mi 04.02.09 11:14

Mist nur wo?
Wie wird die TextLength definiert? Vllt liegt da ja der Fehler .
Bei mir sieht das folgendermaßen aus:
Textlength := Length('FileContens.text');


Delete - Mi 04.02.09 11:36

TextLength müsste doch die Länge des zu ersetzenden Strings sein, wenn ich Deinen Code richtig gedeutet habe.


playsta - Mi 04.02.09 11:47

Ja eigentlich schon.
Mir ist jetzt grade nur noch aufgefallen das egal was ich verändere an textpos und textlengeh , das Programm fügt den Wert immer an der selben Stelle ein ,also immer an der falschen.


Delete - Mi 04.02.09 11:51

Dann versuch es doch einfach mal mit StringReplace.

Delphi-Quelltext
1:
FileContent := StringReplace(FileContent, zuersetzenderString, Memo1.Text,[]);                    


playsta - Mi 04.02.09 11:58

Als fehler gibt er mir das an :[Fehler] Unit1.pas(41): Inkompatible Typen: 'String' und 'TStringList'


Delete - Mi 04.02.09 12:01

Was übergibst Du denn als Parameter?


playsta - Mi 04.02.09 12:04

Ich hab immer noch alles wie beim alten.

procedure TForm1.Button1Click(Sender: TObject);
var

FileContents: TStringList;
textPos,textlength: integer;
begin
FileContents := TStringList.create;
Textlength := Length('FileContens.text');


FileContents.LoadFromFile(OpenDialog1.FileName);
TextPos := Pos('FileContents.Text','##content##') ;
FileContents := StringReplace(FileContents, ##content##, Memo1.Text,[]); ;
ShowMessage(Copy(FileContents.Text, TextPos, TextLength ));

Memo2.Lines.LoadFromFile('text1.txt');
FileContents.SaveToFile('text1.txt');
FileContents.Free;




end;


Delete - Mi 04.02.09 12:07

Achso, dann muss es so heißen:

Delphi-Quelltext
1:
FileContents.Text := StringReplace(FileContents.Text, '##content##', Memo1.Text,[]);                    


playsta - Mi 04.02.09 12:13

Ah, danke danke und nochmals ein danke für die schnelle und freundliche Hilfe.;)