Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi E/A beim Textspeichern (https://www.delphipraxis.net/90161-e-beim-textspeichern.html)

moperswings 12. Apr 2007 15:53


E/A beim Textspeichern
 
Ein Hallo an ALLE,

Ich versuche einen Text zu speichern und bekomme immer - je nachdem welche Variante ich probiere, E/A 32, 104, 105. Ich seh aber den Fehler nicht! Könnt Ihr mal kurz einen Blick drauf werfen, vielleicht sieht ja jemand, woran es hakt!
Viele Grüsse, moperswings
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
        Memo1.SelStart := 3;
end;

procedure TForm1.Memo1OnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
        selstart: integer;
        TempStr2: PChar;
begin
        if key = VK_RETURN then
        begin
        tempStr2 := '</p>';

        SendMessage(Memo1.Handle, EM_Getsel, longint(@selstart), 0);
        SendMessage(Memo1.Handle, EM_Replacesel, 0, LongInt(TempStr2));
        SendMessage(Memo1.Handle, EM_Setsel, selstart + 4, Selstart + 4);
        key := 0;
        end;
end;

procedure TForm1.Memo1OnKeyUP(Sender: TObject; var Key: Word; Shift: TShiftState);
var
        selstart: integer;
        TempStr1: PChar;
begin
        if key = VK_RETURN then
        begin
        tempStr1 := '

';

        SendMessage(Memo1.Handle, EM_Getsel, longint(@selstart), 0);
        SendMessage(Memo1.Handle, EM_Replacesel, 0, LongInt(TempStr1));
        SendMessage(Memo1.Handle, EM_Setsel, selstart + 4, Selstart + 3);
        key := 0;
        end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
        f: textfile;
        dateiname: string;
        count: integer;
        p: string;
begin
        dateiname := 'daten.html';
        Assignfile(f, dateiname);
        {$i-}
        rewrite(f);
        {$i+}
        If IOResult <> 0 then begin
        ShowMessage('Fehler1');
        Exit;
        End;
        Writeln(f, Memo1.Text);
        closefile(f);

        count := 0;
        Assignfile(f, dateiname);
        FileMode := fmOpenRead;
        {$i-}
        reset(f);
        {$i+}
        If IOResult <> 0 then begin
        ShowMessage('Fehler2');
        Exit;
        End;

        While not EOF(f) do begin
        readln(f);
        inc(count);

        p := '</p>';

          if count = 0 then begin
          Writeln(f, Memo1.Text + p);
          closefile(f);
          end
          else
          if count >= 1 then begin
          Memo1.Lines.Delete(Memo1.Lines.Count - 1);
          Writeln(f, Memo1.Text + p);
          closefile(f);
          end;
        end;
end;
end.

mkinzler 12. Apr 2007 16:00

Re: E/A beim Textspeichern
 
Geb mal den vollen Pfad an.

moperswings 12. Apr 2007 16:21

Re: E/A beim Textspeichern
 
Am Pfad liegt´s nicht!
Der Debugger springt jetzt zum letzten Writeln mit E/A 105!

mkinzler 12. Apr 2007 16:50

Re: E/A beim Textspeichern
 
Zitat:

Zitat von Delphi-Hilfe
Behandlung von E/A-Fehlern
Im Status {$I-} wird die Programmausführung fortgesetzt, und der Fehler wird von der Funktion IOResult gemeldet.

E/A-Fehler
Die folgende Tabelle enthält alle E/A-Fehler mit zugehöriger Nummer und einer kurzen Beschreibung.
Nummer
Name
Beschreibung

100
Lesefehler auf Laufwerk
Wird von Read bei dem Versuch gemeldet, den Lesevorgang für eine Textdatei nach dem Dateiende fortzusetzen.

101
Schreibfehler auf Laufwerk
Wird von CloseFile, Write, WriteIn oder Flush gemeldet, wenn auf dem Laufwerk kein freier Speicher mehr verfügbar ist.

102
Datei nicht zugewiesen
Wird von Reset, Rewrite, Append, Rename und Erase gemeldet, wenn der Dateivariablen kein Name zugewiesen wurde (durch einen Aufruf von Assign oder AssignFile).

103
Datei nicht geöffnet
Wird von CloseFile, Read Write, Seek, Eof, FilePos, FileSize, Flush, BlockRead oder BlockWrite gemeldet, wenn die Datei nicht geöffnet ist.

104
Datei nicht für Eingabe geöffnet
Wird von Read, Readln, Eof, Eoln, SeekEof oder SeekEoln gemeldet, wenn die Textdatei nicht für die Eingabe geöffnet ist.

105
Datei nicht für Ausgabe geöffnet
Wird von Write oder Writeln für eine Textdatei gemeldet, wenn keine Konsolenanwendung bereitgestellt wird.

106
Ungültiges Zahlenformat
Wir von Read oder Readln gemeldet, wenn ein aus einer Textdatei gelesener numerischer Wert nicht das richtige Zahlenformat hat.


moperswings 12. Apr 2007 17:01

Re: E/A beim Textspeichern
 
Ich habe mir die Fehlermeldungen schon angesehen.
Nur weiss ich nicht, wo mein Fehler im Code ist.
Entweder ist er generell falsch oder es ist nur eine Kleinigkeit, die ich übersehe!

mkinzler 12. Apr 2007 17:03

Re: E/A beim Textspeichern
 
Vielleicht das CloseFile innerhalb der Schleife?

moperswings 12. Apr 2007 17:19

Re: E/A beim Textspeichern
 
Closefile habe ich schon rausgenommen.
Es hat was mit Fallunterscheidung zu tun, wie das Dokument abgespeichert werden soll. Nehme ich das zweite writeln raus, läufts!

moperswings 12. Apr 2007 17:29

Re: E/A beim Textspeichern
 
Am writeln liegt es nicht!

Es hat was damit zu tun, wie das Dokument zum zweiten mal geöffnet und zum Verarbeiten bereit gestellt wird. So würde ich das Laienhaft einschätzen
Delphi-Quellcode:
...
if count = 0 then Memo1.Lines.Add(</p>)
else
Memo1.Lines.Delete(Memo1.Lines.Count - 1);
end;
writeln(f, Memo1.Text);
Closefile(f);
Jetzt springt er auch zum writeln mit E/A 105

shmia 12. Apr 2007 17:32

Re: E/A beim Textspeichern
 
Mit den beiden folgenden Funktionen, wird das Laden und Speichern zum Kinderspiel:
Delphi-Quellcode:
function FileToString(const FileName: string): AnsiString;
var
  fs: TFileStream;
  Len: Integer;
begin
  fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    Len := fs.Size;
    SetLength(Result, Len);
    if Len > 0 then
      fs.ReadBuffer(Result[1], Len);
  finally
    fs.Free;
  end;
end;

procedure StringToFile(const FileName: string; const Contents: AnsiString);
var
  fs: TFileStream;
  Len: Integer;
begin
  fs := TFileStream.Create(FileName, fmCreate);
  try
    Len := Length(Contents);
    if Len > 0 then
      fs.WriteBuffer(Contents[1], Len);
  finally
    fs.Free;
  end;
end;
Man kann übrigens Daten in einem TMemo ganz einfach laden und speichern
Delphi-Quellcode:
Memo1.lines.LoadFromFile('datei.html');
Memo1.lines.Add('<body>');
Memo1.lines.Add('</body>');
Memo1.lines.SaveToFile('datei.html');

moperswings 12. Apr 2007 17:42

Re: E/A beim Textspeichern
 
Ok, ich beschreibe das Problem! Vielleicht gibt es ja eine ganz andere Lösung!
Ich hab nen Memo mit einem

.
Mit der Enter-Taste füge ich ein </p> ein, d.h. die Tags sind geschlossen und ein neues

wird bereit gestellt.

1. Fall: Der Nutzer schreibt eine Zeile und speichert ohne Enter-Taste, d.h. mir fehlt das </p>, also Memo1.Lines.Add(</p>);

2. Fall: Der Nutzer schreibt mehr und wenn ich speichere ist meine letzte Zeile ja

</p>.
Und diese überflüssige Zeile will ich weg haben, also Memo1.Lines.Delete(Memo1.Lines.count - 1).

Schreibt er aber nur eine Zeile mit Inhalt, würde mir der zweite Fall den Inhalt löschen.
Und aus der Nummer muss ich halt raus kommen!
Andere Vorschläge sind erwünscht!

Ziel: Die Tags sind geschlossen und keine überflüssigen Tags!

moperswings 13. Apr 2007 12:16

Re: E/A beim Textspeichern
 
Wie es aussieht, fange ich mit dieser Lösung - bis jetzt - jeden Fall auf:

Delphi-Quellcode:
Memo1.Lines.Add('</p>');
Writeln(f, Memo1.Text);
closefile(f);

Memo1.Lines.LoadFromFile('d:\editor2\daten.html');
Memo1.Text := StringReplace(Memo1.Text, '

' + #13#10 + '</p>', '', [rfreplaceall]);
Memo1.Text := StringReplace(Memo1.Text, #13#10, '', [rfreplaceall]);
Memo1.Text := StringReplace(Memo1.Text, '

</p>', '', [rfreplaceall]);
umbruch := '</p>' + #13#10 + '

';
Memo1.Text := AnsiReplaceText(Memo1.Text, '</p>

', umbruch);
Memo1.Lines.SaveToFile('d:\editor2\daten.html');
Tschüss, moperswings

shmia 13. Apr 2007 12:36

Re: E/A beim Textspeichern
 
Zitat:

Zitat von moperswings
Ok, ich beschreibe das Problem! Vielleicht gibt es ja eine ganz andere Lösung!
Ich hab nen Memo mit einem

.

Ich verstehe dein Problem nicht so richtig.
Fangen wir mal so an:
Du hast ein TMemo völlig ohne HTML-Tags.
Der Benutzer gibt 3 Zeilen ein:
Zitat:

Zeile 1
Zeile 2 mit etwas mehr Text
Zeile 3
Dann drückt er auf "speichern".
Dein Programm schreibt nun folgendes:
Zitat:


Zeile 1</p>

Zeile 2 mit etwas mehr Text</p>

Zeile 3</p>
Nun möchte der Benutzer die Datei nochmals laden um noch etwas zu editieren.
Das Programm muss dann die Daten als String einlesen und alle Tags entfernen
und die ursprünglichen Zeilenumbrüche wiederherstellen.

Ist es das, was du erreichen möchtest?
Vorteil wäre, dass der Benutzer überhaupt nicht mit den HTML-Tags in Berührung kommt.
Das ganze Gedöns mit OnKeyDown kann man sich sparen.

Muetze1 13. Apr 2007 12:43

Re: E/A beim Textspeichern
 
@moperswings: Du hast dir die Fehlermeldungen schon durchgelesen und es liegt nicht daran? Dann mal kurz Schritt für Schritt:

1. Du öffnest zu Schreiben, schreibst was rein, schliesst die Datei wieder.
2. Du öffnest zum Lesen, liest was aus und danach schreibst in der Schleife in den selben Stream?

Du wunderst dich warum der Fehler 105 bei einem WriteLn() kommt? Und die Beschreibung zum Fehler 105 hilft dir nicht weiter?
Zitat:

Zitat von 105 Hilfe
Datei nicht für Ausgabe geöffnet

Ich wüsste nicht, wie deutlich man es noch hinschreiben sollte. Es steht alles da, es ist alles zusehen - du wurdest darauf hingewiesen und dir selber auch noch Hinweise auf das gegeben was du nicht siehst...

moperswings 13. Apr 2007 12:59

Re: E/A beim Textspeichern
 
@shima, ja so könnte es mal aussehen. Ich taste mich da halt langsam vor, damit ich mit dem Umgang mit Strings mehr Übung erlange.

@muetze: Ich habe - zugegeben - nach dem guten alten Trail and Error-Prinzip mit mehreren Filemodes
und Ein/Ausgaberoutinen gearbeitet, bin aber nicht weiter gekommen. Sonst hätte ich ja nicht gepostet!

Aber letztendlich habe ich es selber so hinbekommen, wie ich es im Moment brauche!
Bestimmt gibt es bessere Lösungen - ich bin für alles offen und dankbar!

Muetze1 14. Apr 2007 00:03

Re: E/A beim Textspeichern
 
Zitat:

Zitat von moperswings
Ich habe - zugegeben - nach dem guten alten Trail and Error-Prinzip mit mehreren Filemodes und Ein/Ausgaberoutinen gearbeitet, bin aber nicht weiter gekommen. Sonst hätte ich ja nicht gepostet!

Das Prinzip kenne ich nicht. Ich hatte früher öfters mal das try and error Prinzip...

FileMode ist nicht der Auslöser sondern die Wahl der Funktion zum Lesen bzw. Schreiben. Also die richtige Auswahl bei Reset, Append und Rewrite.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz