Autor Beitrag
mb
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: So 31.08.03 00:55 
Hallo!

Ich möchte - ganz einfach - eine Textdatei lesen, den Inhalt modifizieren und in eine andere Datei schreiben. Das tue ich - schon seit TP 5 - ganz einfach, inzwischen in Delphi etwas abgewandelt (und bis Delphi 6 hatte es auch immer geklappt):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
AssignFile(f1, "file1.dat");
AssignFile(f2, "file2.dat");
Reset(f1);
ReWrite(f2);
while not eof(f1) do
begin
  ReadLn(f1, s);
  s := ProcessThisStringProc(s);
  WriteLn(f2, s);
end;
CloseFile(f1);
CloseFile(f2);


So in etwa (!) sieht das aus...

Das Ergebnis ist: es kommt eine Datei heraus, die dem Unix-Format ähnelt, was ich in diesem Fall an den Zeilenumbrüchen feststelle... Auch mein Texteditor fragt, ob er die Datei ins DOS/Win-Format konvertieren soll.... Ich frag mich, wie das kommt. In der Datei sind nur ganz normale ASCII-Zeichen, bzw. sogar [0..9,a..z,A..Z].

Ich probier das gerade mit der Trial von Delphi 7; ist da was anders geworden??

Ich wollte zu diesem Zweck ungern auf kompliziertere Methoden zurückgreifen... oder gibt es eine andere gute Möglichkeit??

_________________
Gruß,
MB
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 31.08.03 05:58 
Wie macht denn ProcessThisStringProc die Zeilenumbrüche? Ein Windows Zeilenumbruch sieht so aus: #13#10.
mb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: So 31.08.03 11:03 
Hallöle!

Ja, ich hätte mir denken können, das jemand nach dieser geheimnisvollen Prozedur fragt. ... Diesen Namen hatte ich einfach als Platzhalter eingesetzt. Es werden in wirklichkeit aber nur Zeichen(-ketten) meist am Anfang der Strings verändert.

Gehen wir davon aus, dass ich einfach mit der Funktion
ausblenden Delphi-Quelltext
1:
s := AnsiReplaceText(s, 'fröhlich''traurig');					

den SubString "fröhlich" in "traurig" ersetzen möchte. Dann dürften ja in einem normalen Text auch nicht die Zeilenenden ersetzt werden...
...und die Sourcedatei ist ganz klar eine DOS-formatige Datei mit den Umbrüchen (#13#10).

Und... ich muss den "Unix"-Hinweis wieder zurücknehmen. Es entsteht eine Unicode-Datei (?!) ...jedenfalls werdne pro Zeichen 16Bit verwendet!

_________________
Gruß,
MB
Brueggendiek
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 304

Win 98, Win98SE, Win XP Home
D5 Std
BeitragVerfasst: So 31.08.03 11:13 
Hallo MB!

Da solltest Du mal die Onlinehilfe (F1) befragen, ob D7 vielleicht standardmäßig für Strings Widestrings einsetzt!

Die Verwendung von Strings ist ja beim Übergang von Turbo-Pascal auf Delphi schon mal geändert worden - in TP war STRING identisch mit STRING[255] - das muß man bei D5 als "Shortstring" deklarieren, während STRING jetzt "Ansistring" ist mit bis zu 2GB, mit 8 Bit pro Zeichen.

Möglich, daß bei D7 das auf "Widestring" geändet wurde - das ist der Unicode-String mit 16 Bits pro Zeichen!

Ist natürlich nur so eine Vermutung, aber bei dem Fehlerbild kann ich mir nichts anderes vorstellen.

Nimm doch eventuell mal die Umwandlung ganz raus, so daß ein reines Kopierprogramm entsteht - vielleicht bewirkt die Umwandlung ja auch den 16-Bit-Effekt.

Gruß

Dietmar Brüggendiek
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: So 31.08.03 12:19 
hmmm... mit den Zeilenumbrüchen? also ich bin der meinung, dass das einzig und allein an dem "WriteLn(f2, s);" liegt. weil das macht ja noch nen Zelenumbruch. und ich mein "ReadLn" ließt den Zeielnumbruch gar nich mit, wenn ich mich recht daran erinnere. heißt, in "s" is nacher nich am schluß ein #13#10 und auch kein #13 (wie das bei Unix aussieht). also wenns nich an diesem Unicode liegt (wovon ich (zu meiner Schande) keine ahnung hab ;) ), dann liegt das an dem WriteLn meiner Ansicht nach...



MrSaint

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
mb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: So 31.08.03 12:29 
Ja, dass es am WriteLn liegt dachte ich auch schon... Wie würdet ihr denn ne reine Textdatei auslesen und schreiben, wenn nicht mit ReadLn und WriteLn? Mit Write() kann ich ja keine untypisierte Datei schreiben, sonst hätt ich ja den Zeilenumbruch selbst dranhängen können.

Das mit AnsiString, WideString, ... werd ich noch mal prüfen.

Danke trotzdem soweit.

_________________
Gruß,
MB
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: So 31.08.03 12:32 
es gibt ja noch die API Funktionen. ich glaub das waren fileopen(..), filewrite(..), fileread(...). geb aber keine garantie dafür, weil ich die datei-funktinen irgendwie immer durcheinander bring ;)

MrSaint

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 31.08.03 12:44 
Es muß auch mit writeln gehen. Aber kuck mal, ob D7 nicht wirklich standardmäßig WideStrings nimmt.
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: So 31.08.03 13:03 
Hallo,
Luckie hat folgendes geschrieben:
Es muß auch mit writeln gehen. Aber kuck mal, ob D7 nicht wirklich standardmäßig WideStrings nimmt.

ich habe gerade mal ein wenig in mainer D7 hilfe gestöbert. Dieses könnte für mb interessant sein:
Delphi 7 Hilfe hat folgendes geschrieben:
Das reservierte Wort string funktioniert wie ein generischer Typbezeichner:

var S: string;

Hier wird beispielsweise die Variable S für einen String erstellt. Im voreingestellten Status {$H+} interpretiert der Compiler string als AnsiString (wenn auf das reservierte Wort keine Zahl in eckigen Klammern folgt). Bei Verwendung der Direktive {$H?} wird string als ShortString interpretiert.


Danach wird nicht standarmäßig WideString verwendet.

Es gab ein paar änderungen an den StrUtils:
Delphi 7 Hilfe hat folgendes geschrieben:
Unit StrUtils

Die Unit StrUtils weist folgende Änderungen hinsichtlich der Unterstützung von Multibyte-Zeichensätzen (MBCS) auf:
  • In älteren Versionen konnte an LeftStr, RightStr und MidStr nur ein AnsiString-Parameter übergeben werden. Der Rückgabewert war ebenfalls auf den Typ AnsiString beschränkt. Multibyte-Zeichensätze (MBCS) wurden nicht unterstützt. In der neuen Version wurde jede dieser Funktionen durch ein Paar überladener Funktionen ersetzt, von denen jeweils eine AnsiString-Parameter und -Rückgabewerte und die andere WideString-Parameter und Rückgabewerte unterstützt. MBCS-Strings werden von den neuen Funktionen verarbeitet. Aufgrund dieser Änderung ist Quelltext, in dem diese Funktionen zum Speichern und Abrufen von Byte-Werten in AnsiStrings eingesetzt werden, nicht mehr funktionsfähig und muss (unter Verwendung der nachstehend beschriebenen neuen Funktionen auf Byte-Ebene) umgeschrieben werden.
  • Die neuen Funktionen LeftBStr, RightBStr und MidBStr werden für Operationen auf Byte-Ebene eingesetzt, die früher mithilfe von LeftStr, RightStr und MidStr implementiert wurden.
  • Die neuen Funktionen AnsiLeftStr, AnsiRightStr und AnsiMidStr entsprechen den neuen Funktionen AnsiStr, LeftBtr, RightStr und MidStr, sind aber im Gegensatz zu diesen nicht mit WideString-Funktionen überladen.

Die Unit StrUtils enthält die neue Funktion PosEx für die Stringsuche.

vieleicht ergeben sich dadraus konpflikte.

@MB du könntest ja sicherheitshalber mal versuchen, deinen String vor dem Schreiben zu Typecasten. Also so:
ausblenden Delphi-Quelltext
1:
WriteLn(f2, AnsiString(s));					


Gruß
Klabautermann
mb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: So 31.08.03 13:34 
Danke für die Antworten. Dennoch, hier der nicht ganz erfolgreiche Zwischenstatus...

Ich habe folgendes probiert...

ausblenden Delphi-Quelltext
1:
2:
3:
{$H-}
var s: String;
{$H+}

...kein Erfolg

ausblenden Delphi-Quelltext
1:
 var s:ShortString;					

...kein Erfolg

ausblenden Delphi-Quelltext
1:
 WriteLn(f2, AnsiString(s));					

...kein Erfolg

Selbst, wenn ich die Datei nur kopiere mit
ausblenden Delphi-Quelltext
1:
2:
ReadLn(f1, s);
WriteLn(f2, s);

...kommt nix gutes dabei raus. Es liegt also nicht an der Bearbeitung des Strings...

Da bin ich nun ehrlich gesagt etwas ratlos.

Andere Frage: Falls ich doch andere Zugriffsmethoden benutzen würde, so müsste ich die Datei dennoch Zeilenweise auslesen können; das geht aber ja AFAIK nicht mit FileWrite() und FileRead() ... oder BlockRead(), etc... oder? Ich will ja kein Array/Puffer auslesen, sondern eben immer bis zum Zeilenende. (...und das müsste m.E. einfacher gehen, als einen Puffer zu lesen und dann auf ^M^J / #13#10 o.ä zu untersuchen)

_________________
Gruß,
MB
Klabautermann
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Veteran
Beiträge: 6366
Erhaltene Danke: 60

Windows 7, Ubuntu
Delphi 7 Prof.
BeitragVerfasst: So 31.08.03 14:28 
Hallo,

du könntest ein Objekt vom Typ tStringList erzeugen, und dessen ReadFromFile und WriteToFile Methoden verwenden.
Über
ausblenden Delphi-Quelltext
1:
MyStringlistObject[i]					

kannst du auf die einzelnen Zeilen zugreifen.

Aber dass mit dem ReadLn, WriteLn wundert mich.

Gruß
Klabautermann
recall
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 449



BeitragVerfasst: So 31.08.03 23:02 
Hallo,

von welchem Typ sind denn dein f1 bzw. f2 ? TextFile ?
Nicht: "file of String" , oder ??
(daran könnts liegen)

Viele Grüsse.

P.S.: Bei mir läufts einwandfrei :D .

//EDIT: Habe auch D7 (vergessen)
mb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: Mo 01.09.03 09:57 
Ja, meine Deklaration in diesem Bereich ist/war
ausblenden Delphi-Quelltext
1:
var f1, f2: TextFile;					


(Das muss ja auch irgendwie so sein, dass mir ein ganz blöder Fehler unterlaufen ist... ?!)

Dennoch: File of String akzeptiert Delphi auch nicht. Früher unter TP/BP war das ja mit  var f1,f2: Text; getan. Seit sich das geändert hat, habe ich es immer erfolgreich (!) mit TextFile gemacht...

Aber zurückzu "File of String". Der Compiler meckert, dass der Typ String eine Finalisierung braucht, die im File type nicht erlaubt ist.

Wenn ich stattdessen File of ShortString oder ... String[255] einsetze, dann erhalte ich in meiner ReadLn(f1, s) - Codezeile die Meldung, dass die Typen inkompatibel sind.

@Klabauterman: Danke für diesen Tipp. Ich werde den gleich mal probieren.

_________________
Gruß,
MB
mb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: Mo 01.09.03 10:35 
Na ja, irgendwie stell ich mich wohl blöd an... Ich glaub, an so einer einfachen Sache saß ich noch nie so lange...

Also, hab umgestellt auf TStringList ... etwa so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
 var f: TStringList;
  .
  .
  .
     f := TStringList.Create;
      try
        f.LoadFromFile(fn);
        f.SaveToFile(ChangeFileExt(fn, '.bak'));
      finally
        f.Free;
      end;


Das Ergebnis ist: die erzeugte Datei ist leer. Besser gesagt: Bei LoadFromFile passiert schlichtweg nichts, es wird kein Inhalt in die Stringliste gelesen...

_________________
Gruß,
MB
mb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: Mo 01.09.03 10:37 
recall hat folgendes geschrieben:
P.S.: Bei mir läufts einwandfrei


Könntest Du mal einen Sourceabschnitt posten, der bei dir compiliert wird und auch "semantisch" korrekt funktioniert ?

_________________
Gruß,
MB
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 01.09.03 10:53 
mb hat folgendes geschrieben:
Das Ergebnis ist: die erzeugte Datei ist leer. Besser gesagt: Bei LoadFromFile passiert schlichtweg nichts, es wird kein Inhalt in die Stringliste gelesen...

Existiert die Datei? Was steht in der Datei drinnen?

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
recall
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 449



BeitragVerfasst: Mo 01.09.03 12:34 
@mb: Ich habe den ersten Quelltext von dir genommen (natürlich ohne s := ProcessThisStringProc(s); ), mit var f1,f2: TextFile; und das ganze in ein Button-OnClick-Ereignis getan...
Dann noch eine existierende Textdatei rausgesucht, fertig.

Hat funktioniert.
Vielleicht ist irgendwas mit deiner unit "system" nicht richtig ?!
Vielleicht neu installieren ?

Hast du Windows ME ? Da funktionierte bei mir die ini-Fileverwaltung nicht :( und auch einige andere Dateizugriffe murksten rum.
(Werde dazu noch einen Thread aufmachen ;) ).

Viele Grüsse.
barfuesser
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 324



BeitragVerfasst: Mo 01.09.03 12:34 
@mb: Hast Du Dir schon mal die Ursprungsdatei angesehen? Nicht das in dieser Datei schon der Fehler liegt.

barfuesser
mb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 185



BeitragVerfasst: Mo 01.09.03 13:15 
Hallo - erst noch mal "danke" für Eure Teilnahme / Beteiligung an meinem Problem...
...irgendwie hört sich das ganze lächerlich an und dennoch finde ich echt den Fehler nicht.

Zu den Fragen:
Ja, die Datei existiert. Ich habe es auch schon mit anderen testweise probiert. Die Funktion ist ja inzwischen nur auf das kopieren (einlesen und wieder schreiben) reduziert ... selbst das funktioniert nicht.

Im Original-Quelltext sind sowieso noch weitere try-catch-Blöcke (sorry: ...except ;-)) vorhanden. Also, wenn da ein Fehler auftreten würde, müsste ich es merken (Exception).

Ratlos....

_________________
Gruß,
MB
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 01.09.03 13:23 
Beantworte doch mal bitte dir Frage von barfuesser!