Entwickler-Ecke

Dateizugriff - Daten aus Datei auslesen, verändern und dann speichern.


Dhakiyah - Mi 17.09.08 13:33
Titel: Daten aus Datei auslesen, verändern und dann speichern.
Hallo!
Ich habe eine *.txt Datei wo Namen drin stehen.

Beispiel:
Max Mustermann
Angela Merkel
Helmut Kohl
usw.

Die Daten will ich öffnen und dann verändern in:

Max.Mustermann@email.de
Angela.Merkel@email.de
Helmut.Kohl@email.de
usw.

Und die sollen wiederum gespeichert werden.

Wie mache ich das?
Ich habe keinen Plan...

LG


jaenicke - Mi 17.09.08 14:56

TStringList, LoadFromFile, Schleife, i-te Zeile:

Delphi-Quelltext
1:
2:
Zeile[Pos(' ', Zeile)] := '.';
Zeile := Zeile + '@email.de';

Problem: Mehrere Vornamen, da musst du ggf. mehrfach den Punkt setzen bis kein Leerzeichen mehr da ist (Pos = 0).

// EDIT:
Ich habe gerade deinen anderen Beitrag gelesen ;-), wenn das hier zu stichwortartig ist, kann ich auch noch ausführlicher werden.


Dhakiyah - Mo 22.09.08 13:33
Titel: Hallo
Ja, bitte...
Ich komme irgendwie nicht dahinter wie man Dateien öffnet, einliest, ausliest usw...

Ich weiß ich muss die Datei öffnen, dann die Namen und Vornamen in einen String schieben und die dann zusammen tun + dem . zwischen dem Vor und Nachnamen und dann plus dem @blablabla.de

Aber wie???

LG
Jasmin


jaenicke - Di 23.09.08 05:03

Aaaalso:
Zuerst deklarierst du eine Variable vom Typ TStringList:

Delphi-Quelltext
1:
2:
var
  Dateiinhalt: TStringList;
Dann erzeugst du das Objekt und packst es in diese Variable um damit zu arbeiten:

Delphi-Quelltext
1:
  Dateiinhalt := TStringList.Create;                    
Nun lädst du den Inhalt der Datei in die Stringliste (in diesem Fall aus der Datei test.txt im selben Verzeichnis wie das Programm).

Delphi-Quelltext
1:
  Dateiinhalt.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'test.txt');                    
Jetzt gehst du in einer Schleife durch alle Zeilen

Delphi-Quelltext
1:
  for i := 0 to Dateiinhalt.Count - 1 do                    
Jetzt kannst du auf die einzelnen Zeilen mit Dateiinhalt[i] zugreifen, diese Zeile speicherst du jetzt erstmal in einer Variablen Zeile, um damit zu arbeiten. Mit Pos ermittelst du die Position des ersten Leerzeichens in der Zeile. Dann schreibst du an diese Stelle einen Punkt.

Delphi-Quelltext
1:
2:
  Zeile := Dateiinhalt[i];
  Zeile[Pos(' ', Zeile)] := '.';
Jetzt hängst du noch jeweils @email.de an die Zeile an und legst die neue Zeile wieder in die Zeile der Stringliste

Delphi-Quelltext
1:
  Dateiinhalt[i] := Zeile + '@email.de';                    
Nun speicherst du noch die neue Liste

Delphi-Quelltext
1:
  Dateiinhalt.SaveToFile(ExtractFilePath(ParamStr(0)) + 'test2.txt');                    
und gibst den Speicher, den du für die Stringliste benutzt hast, wieder frei

Delphi-Quelltext
1:
  Dateiinhalt.Free;                    


Und jetzt nochmal zusammenhängend: ;-)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  Dateiinhalt: TStringList;
  i: Integer;
  Zeile: string;
begin
  Dateiinhalt := TStringList.Create;
  Dateiinhalt.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'test.txt');
  for i := 0 to Dateiinhalt.Count - 1 do
  begin
    Zeile := Dateiinhalt[i];
    Zeile[Pos(' ', Zeile)] := '.';
    Dateiinhalt[i] := Zeile + '@email.de';
  end;
  Dateiinhalt.SaveToFile(ExtractFilePath(ParamStr(0)) + 'test2.txt');
  Dateiinhalt.Free;


Wenn das ganze auch mehrere Leerzeichen ersetzen soll, dann musst du solange das jeweils nächste ersetzen bis keins mehr da ist, also statt

Delphi-Quelltext
1:
    Zeile[Pos(' ', Zeile)] := '.';                    
eine Schleife:

Delphi-Quelltext
1:
2:
    while Pos(' ', Zeile) > 0 do
      Zeile[Pos(' ', Zeile)] := '.';


Dhakiyah - Di 23.09.08 09:16
Titel: Huhu
Wärst du so nett und würdest mir das ganze noch mit Word und Excel erklären?

Bei Word wird es ja so ähnlich sein wie bei *.txt.
Aber wie gehts in Excel?
Also Namen Spalte 1, Vornamen Spalte 2 und das Ergebnis soll in Spalte 3.

Wäre super lieb.
DANKE.

LG
Jasmin


Narses - Di 23.09.08 11:24
Titel: Re: Huhu
Moin!

user profile iconDhakiyah hat folgendes geschrieben:
Bei Word wird es ja so ähnlich sein wie bei *.txt.
Aber wie gehts in Excel?
Also Namen Spalte 1, Vornamen Spalte 2 und das Ergebnis soll in Spalte 3.
Wie wäre es mit fertigem Quelltext? :nixweiss: Spaß beiseite... :D

Das Word-Dateiformat ist nicht öffentlich, dito bei Excel. Hier bleibt eigentlich nur der Weg über OLE-Zugriffe, aber das ist ein ganz anderes Thema und deshalb wird das nicht hier besprochen. :|

Wenn du dazu konkrete Fragen hast, dann erstelle dazu bitte einen neuen Thread. ;)

cu
Narses


Logikmensch - Mi 24.09.08 06:24

Ich würd' auf jeden Fall statt


Delphi-Quelltext
1:
Zeile[Pos(' ', Zeile)] := '.';                    

folgendes schreiben, weil bei einem fehlenden Leerzeichentrenner ein Laufzeitfehler ausgelöst wird (Pos => 0):


Delphi-Quelltext
1:
2:
3:
Zeile := Trim (Zeile); //Löscht evtl. Leerzeichen am Anfang und am Ende des Namens
p := Pos(' ',Zeile);
if p > 0 then Zeile[p]:='.';

Und will man auch Johann Sebastian Bach berücksichtigen ;-) dann empfiehlt sich auch eine Schleife:


Delphi-Quelltext
1:
2:
3:
Zeile := Trim (Zeile);
for p := 1 to Length(Zeile) do
  if Zeile[p] = ' ' then Zeile[p] := '.';


Dhakiyah - Mi 24.09.08 12:43
Titel: Dateizugriff
Hallo!
Ich habe das jetzt mal so gemacht und dann kommt ein Fehler:

Zugriffsverletzung bei Adresse 004030B4 in Modul 'Projekt.exe'. lesevn von Adresse 00AA1000.

Wenn ich das ignoriere dann kommt zu wenig Arbeitsspeicher... :shock:

Ersetze ich diese eine Zeile durch das, was Logikmensch geschrieben hat, dann geht es, dann ersetzt er aber '' nicht mehr durch '.'...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var Datei: TStringList;
    i, p: Integer;
    Zeile: string;
begin
  Datei := TStringList.Create;
  Datei.LoadFromFile(ExtractFilePath(ParamStr(0))+ 'name.txt');
  for i := 0 to Datei.Count - 1 do
    begin
      Zeile := Datei[i];
      Zeile := Trim (Zeile);
      for p := 1 to Length(Zeile) do
      if Zeile[p] = ' ' then Zeile[p] := '.';
      Datei[i] := Zeile + '@email.de';
    end;
  Datei.SaveToFile(ExtractFilePath(ParamStr(0)) + 'name2.txt');
  Datei.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Memo1.Lines.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'name.txt');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Memo2.Lines.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'name2.txt')
end;

end.


Gruß


tif - Mi 24.09.08 12:49

Ist Zeile vielleicht leer ?


Delphi-Quelltext
1:
2:
3:
4:
Zeile := Trim (Zeile);
if length(zeile) > 0 then
  for p := 1 to Length(Zeile) do
     if Zeile[p] = ' ' then Zeile[p] := '.';

oder

Delphi-Quelltext
1:
2:
3:
4:
5:
p:=pos(' ',Zeile);
while p > 0 do begin
  zeile[p]:='.';
  p:=pos(' ',Zeile);
end;


Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Dhakiyah - Mi 24.09.08 12:56
Titel: Dateizugriff
Hm... Geht beides nicht...

Gruß


Delete - Mi 24.09.08 12:56
Titel: Re: Huhu
user profile iconNarses hat folgendes geschrieben:
Das Word-Dateiformat ist nicht öffentlich, dito bei Excel.


M$ hat die beiden formate veröffentlicht, was IMHO nicht öffentlich ist, ist die OOXML von M$, welche von M$ verwendet wird. die ISO Version, von OOXML verwendet ja niemand, welche öffentlich ist ;-)


Narses - Mi 24.09.08 13:27
Titel: Re: Huhu
Moin!

user profile iconGrenzgaenger hat folgendes geschrieben:
M$ hat die beiden formate veröffentlicht,
Danke für den Hinweis, aber bzgl. dieses Themas ist in diesem Thread jetzt bitte Ende! :|

cu
Narses


Dhakiyah - Mo 29.09.08 08:40
Titel: Hallo...
Es geht immer noch nicht.
Der ersetzt ' ' nicht durch '.' .
Er lässt einfach die Leerzeichen wie sie sind.

LG
Jasmin


Delete - Mo 29.09.08 09:49

Und so?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Button1Click(Sender: TObject);
var Datei: TStringList;
    i: Integer;
    Zeile: string;
begin
  Datei := TStringList.Create;
  try
    Datei.LoadFromFile(ExtractFilePath(ParamStr(0))+ 'name.txt');
    for i := 0 to Datei.Count - 1 do
      begin
        Zeile := StringReplace(trim(Datei[i]),' ','.',[rfReplaceAll]);
        Datei[i] := Zeile + '@email.de';
      end;
    Datei.SaveToFile(ExtractFilePath(ParamStr(0)) + 'name2.txt');
  finally
    Datei.Free;
  end;
end;


Dhakiyah - Mo 29.09.08 09:56
Titel: Immer noch nicht . . .
Hallo!
Mir ist grad was aufgefallen *hust*

Also in der ersten Textdatei sind mehrere Lehrstellen, vielleicht liegt es daran.
Sorry, daran habe ich nicht gedacht...

Also zum Beispiel:
Helmut Kohl
Angela Merkel
Kurt Beck

usw.

Gruß
Jasmin


Delete - Mo 29.09.08 09:58

Das sollte aber egal sein, es sollen ja alle Leerzeichen ersetzt werden. Bist Du Dir auch sicher, dass das wirklich Leerzeichen(#32) sind?


Dhakiyah - Mo 29.09.08 10:00
Titel: Re: Immer noch nicht . . .
Ach jetzt habe ich mich verdrückt... Egal...
Also was bedeutet #32?
Also er macht es nicht. Die Leerstellen bleiben so wie sie sind.

Gruß

Moderiert von user profile iconNarses: Selbstzitat entfernt ;)


Delete - Mo 29.09.08 10:09

Ein Leerzeichen hat den ASCII-Code 32, das wird #32 geschrieben. Möglicherweise sind das aber auch Tabulatoren in Deiner Textdatei, die haben dann den ASCII-Code 9 und werden von den o.a. Codes nicht gefunden.


Dhakiyah - Mo 29.09.08 10:12
Titel: Hallo...
Ähm... Wie finde ich das raus? Das ist natürlich möglich...

Mal eine Frage bezüglich dem Thema hier:
Was ist der Unterschied zwischen TString und TStringList?

Und wie muss ich mir das vorstellen wie das dort drinne steht? Genau wie in der Textdatei? Könnte ich zum Beispiel Person Nr. 5 ansprechen?

Grüße


Delete - Mo 29.09.08 10:23

Dhakiyah hat folgendes geschrieben:
Wie finde ich das raus?

Öffne mal die Datei im Editor, setz den Cursor vor das erste "Leerzeichen" und lösch es mal. Wenn der ganze Rest der Zeile daraufhin "springt", wird es wohl ein Tabulator gewesen sein.


Dhakiyah - Mo 29.09.08 10:28
Titel: Hallo...
Ja, es sind Tabs... Und nu?

Gruß


Delete - Mo 29.09.08 10:32


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Button1Click(Sender: TObject);
var Datei: TStringList;
    i: Integer;
    Zeile: string;
begin
  Datei := TStringList.Create;
  try
    Datei.LoadFromFile(ExtractFilePath(ParamStr(0))+ 'name.txt');
    for i := 0 to Datei.Count - 1 do
      begin
        Zeile := StringReplace(trim(Datei[i]),#9,'.',[rfReplaceAll]); //Tabs ersetzen
        Datei[i] := Zeile + '@email.de';
      end;
    Datei.SaveToFile(ExtractFilePath(ParamStr(0)) + 'name2.txt');
  finally
    Datei.Free;
  end;
end;


Oder nimm Dir eine der anderen geposteten Lösungen und ersetze dort ' ' durch #9 ;)


bf109g.01 - Mi 01.10.08 11:27
Titel: Fehlermeldung beim (mehrfachen) Abspeichern.
hallo, hab ein thematisch sehr ähnliches Problem, von daher schreibe ich das mal hier dazu. Sry, wenns fehl am Platz ist, dann bitte verschieben... :?

Ich würde gern eine Datei (.txt / .log / ...) laden (Memo), ändern (manual) und abspeichern (Ursprungsdatei).
Damit die Datei beliebig sein kann und nicht nur eine bestimmte, benutze ich eine 'TOpenDialog'-Funktion.
Dann soll die Datei abgespeichert werden.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
var
  F: TF;
  dateiname: string;
implementation

{$R *.dfm}

// Laden einer externen .txt-datei + Einfügen in Memo
procedure TF.BloadClick(Sender: TObject);
begin
if OD1.Execute then M.Lines.LoadFromFile(OD1.FileName);
dateiname:= od1.FileName;
{showmessage(dateiname) (Kontrolle)};
end;

// Abspeichern der Änderungen
procedure TF.BsaveClick(Sender: TObject);
begin
  M.Lines.SaveToFile(dateiname);
  M.Lines.Free;  // Was heißt das??? 
end;

end.


Das Abspeichern funktioniert, aber nur 1 Mal.
Wenn ich danach wieder auf Speichern klicke, bekomme ich folgende Meldung:

Zitat:
Exception EInvalidPointer in Modul Project1.exe bei 00003821
Ungültige Zeigeroption


Habe keine Ahnung, was das bedeuten soll. Wo kommt das her? Wie krieg ich's weg?

Fürs mehrfache Laden gilt übrigens das selbe: 1-2 Mal lade ich eine neue Datei rein, nachdem ich die erste gespeichert habe und ich kriege wieder fehlermeldungen und es läuft nix mehr.

Vielen Dank schon mal.


Delete - Mi 01.10.08 11:48


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
var
  F: TF;
  dateiname: string;
implementation

{$R *.dfm}

// Laden einer externen .txt-datei + Einfügen in Memo
procedure TF.BloadClick(Sender: TObject);
begin
  if OD1.Execute then 
    begin //<--
      M.Lines.LoadFromFile(OD1.FileName);
      dateiname:= od1.FileName;
    end//<--
{showmessage(dateiname) (Kontrolle)};
end;

// Abspeichern der Änderungen
procedure TF.BsaveClick(Sender: TObject);
begin
  M.Lines.SaveToFile(dateiname);
  M.Lines.Clear;  // So sollte es wohl heißen 
end;

end.