Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Beginner: Textverarbeitung (https://www.delphipraxis.net/191022-beginner-textverarbeitung.html)

jdiephaus 30. Nov 2016 14:13

Delphi-Version: 5

Beginner: Textverarbeitung
 
Hallo Liebe Community,
ich bin mittlerweile beim Thema Textverarbeitung angekommen. Hier mein Code:

Delphi-Quellcode:
program Textverarbeitung;
   {$APPTYPE CONSOLE} uses sysutils;
var textout,textin: Text;
    ch: Char;
begin
  Assignfile(textin,'test.in'); Assignfile(textout,'test.out');
  RESET(textin); REWRITE(textout); //Anfang textin  Erzeugt leeres textout
  while not(eof(textin)) do      //eof True wenn Dateiende
  begin
    if eoln(textin) then         //eoln True wenn Zeilenende
       begin
         writeln(textout);       //Schreibt eingelesene Zeile in textout?
         readln(textin)          //Liest nächste Zeile ein? Kein Semikolon?
       end                       //Kein Semikolon?
    else
      begin
         read(textin,ch);        //Liest nächstes Zeichen aus textin, schreibt in ch?
         write(textout,ch);      //Schreibt Zeichen aus ch in textout?
      end;
  end;
  CloseFile(textout);            //Schließt textout
  readln();
  end.
Ich verstehe die Funktionsweise noch nicht ganz :roll: Das Programm liest Text aus textin und schreibt ihn in textout. Funktioniert auch soweit.

Die Aufgabe lautet (falls ich den Code endlich genau verstehen würde):
- Es soll die Anzahl der Zeichen inkl. Leerzeichen gezählt werden
- Es soll die Anzahl der Worte gezählt werden

Ich habe jetzt schon einiges zum Thema Textverarbeitung gelesen auch hier im Forum, jedoch ist der Code da immer so fortgeschritten geschrieben das ich schon nicht mehr durchsteige. Procedure hier Procedure da :pale:

Meine Idee ist es die Anzahl von ch zu lesen die in textout geschrieben wird. ch in einen String zu schreiben und dann mit inttostr eine Integerzahl mit der Anzahl der geschriebenen Chars zu erzeugen. Klingt das soweit logisch?

Mit dem Zählen der Worte würde ich es dann ähnlich machen. Ich würde versuchen Wörter zu definieren als durch Leerzeichen (' ') oder Zeilenumbruch voneinander getrennte Strings. Macht das Sinn?

Ich hoffe ich konnte mich einigermaßen verständlich ausdrücken. Vielen Dank für eure Mühe. Ich weiß das sehr zu schätzen!

Klaus01 30. Nov 2016 14:23

AW: Beginner: Textverarbeitung
 
.. Zeilenende erkennst Du wenn ch = Carriage Return ist und das nächste Zeichen ch = Linefeed ist.
Ein Wort erkennst Du wenn einem Zeichen ein oder mehrere Leerzeichen folgen.

Grüße
Klaus

jdiephaus 30. Nov 2016 14:32

AW: Beginner: Textverarbeitung
 
Okay vielen Dank erstmal Klaus!

Wie kann ich den Status Carriage Return oder Linefeed aus ch auslesen?

Habe ich den Code (so wie ich ihn kommentiert habe) richtig verstanden?

Edit: Kann ich dafür ord(ch) nutzen? 32 ist in dem Fall ein Leerzeichen.

Klaus01 30. Nov 2016 14:44

AW: Beginner: Textverarbeitung
 
Hallo,

in einer Ascii Tabelle nachschauen -> http://www.torsten-horn.de/techdocs/ascii.htm
LF = #10
CR = #13

Grüße
Klaus

Jumpy 30. Nov 2016 14:49

AW: Beginner: Textverarbeitung
 
So wie du den Code planst brauchst du das mMn gar nicht wissen. Immer wenn ein eoln war, ausser beim letzten mal, müsste doch ein neues Wort sein, wenn man jetzt mal davon ausgeht, dass es keine Silbentrennung im Text gibt und Worte die ohne Silbentrennung in der nächsten Zeile weiter gehen.

Dann bräuchtest du nur 2 Zählvariablen. Eine für AnzZeichen und eine Für AnzWort. Am Anfang beide 0.
im else zweig steigt jedes mal AnzZeichen und wenn ch=' ' dann auch AnzWort. Hier evtl. Sonderfall mehrerer Leerzeichen hintereinander betrachten, z.B. durch speichern des vorherigen Zeichens.
Und dann "könnte" sich bei jedem eoln auch die Wortzahl erhöhen (wenn nicht gleich auch eof ist).

himitsu 30. Nov 2016 15:05

AW: Beginner: Textverarbeitung
 
Zitat:

Delphi-Quellcode:
       end //Kein Semikolon?
    else
      begin

Nein, wegen dem ELSE.
Zitat:

Delphi-Quellcode:
         readln(textin) //Kein Semikolon?
       end

Man könnte es weglassen, weil danach ein END folgt, aber besser immer machen, da der Befehl ja zuende ist.

Fazit: Semikolon immer, außer vor ELSE, da dort der Gesamt-Befehl (inkl. IF) noch nicht endet.


Zitat:

Delphi-Quellcode:
         writeln(textout); //Schreibt eingelesene Zeile in textout?
         readln(textin) //Liest nächste Zeile ein? Kein Semikolon?

Variable vergessen. (string)
Und wäre es nicht besser erst einzulesen und dann zu Gelesene speichern? :zwinker:

PS: Delphi-Referenz durchsuchenTStringList

Whookie 30. Nov 2016 15:08

AW: Beginner: Textverarbeitung
 
Delphi-Quellcode:
program Textverarbeitung;
{$APPTYPE CONSOLE} uses sysutils;
var textout,textin: Text;
    ch: Char;
begin
  Assignfile(textin,'test.in');
  Assignfile(textout,'test.out');
  RESET(textin);   // Datei textin öffnen
  REWRITE(textout); // Datei textout zum überschreiben öffnen
  while not(eof(textin)) do //eof True wenn Dateiende
  begin
    if eoln(textin) then //eoln True wenn Zeilenende
    begin
      writeln(textout); // Schreibt <cr><lf> in die textout Datei
      readln(textin);  // Liest <cr><lf> aus der textin Datei (und verwirft es) <- Kein Semikolon nötig (es ist aber auch nicht verboten eins zu machen!!)
    end // kein Semikolon, weil der block mit "else" weiter geht
    else
    begin
      read(textin,ch);  // Liest ein Zeichen aus der textin - Datei
      write(textout,ch); // schreibt das soeben gelesene Zeichen in die textout - Datei
      // hier kann einfach ein Zeichenzähler geführt werden.
      // platz für den Wortzähler...
    end;
  end;
  CloseFile(textout); //Schließt textout
  CloseFile(textin); //Schließt textin
  readln();
end.

Schreib stets nur eine Anweisung pro Zeile, das ist dann auch besser zu kommentieren (und später auch zu debuggen).
Das erste Semikolon "kann" weggelassen werden, weil es die letzte Anweisung vor dem "End" ist - "muss" aber nicht, ich empfehle dir es immer zu setzen.
Das zweite Semikolon ist nicht erlaubt, weil der begin/end-Block über das "else" noch nicht abgeschlossen ist.
Dateien die du öffnest solltest du auch wieder schließen, das gilt auch für textin.

Zum Zählen gibts hier ohnehin schon Hinweise und selber lösen macht bekanntlich schlauer :thumb:

Whookie 30. Nov 2016 15:16

AW: Beginner: Textverarbeitung
 
Zitat:

Zitat von himitsu (Beitrag 1355045)

Zitat:

Delphi-Quellcode:
         writeln(textout); //Schreibt eingelesene Zeile in textout?
         readln(textin) //Liest nächste Zeile ein? Kein Semikolon?

Variable vergessen. (string)
Und wäre es nicht besser erst einzulesen und dann zu Gelesene speichern? :zwinker:

Nein das passt schon so :-D
Es wird das Zeilenende erkannt und danach in die Ausgangsdatei geschrieben. Es muss natürlich dann auch noch von der Eingangsdatei entfernt werden.

jdiephaus 30. Nov 2016 16:07

AW: Beginner: Textverarbeitung
 
Delphi-Quellcode:
program Textverarbeitung;
{$APPTYPE CONSOLE} uses sysutils;
var textout,textin: Text;
    ch: Char;
    AnzZeichen: Integer;
    AnzWort: Integer;
begin
  Assignfile(textin,'test.in');
  Assignfile(textout,'test.out');
  RESET(textin);                // Datei textin öffnen
  REWRITE(textout);             // Datei textout zum überschreiben öffnen
  AnzZeichen:=0;                // Startwert AnzZeichen
  AnzWort:=0;                   // Startwert AnzWort
  while not(eof(textin)) do     // eof True wenn Dateiende
  begin
    if eoln(textin) then        // eoln True wenn Zeilenende
    begin
      writeln(textout);         // Schreibt <cr><lf> in die textout Datei
      readln(textin);           // Liest <cr><lf> aus der textin Datei (und verwirft es)
    end
    else
    begin
      read(textin,ch);          // Liest ein Zeichen aus der textin - Datei
      write(textout,ch);        // Schreibt das soeben gelesene Zeichen in die textout - Datei
       Inc(AnzZeichen,1);       // Zählt die Anzahl der Zeichen inkl. Leerzeichen
       If eoln(textin) then
          Inc(AnzWort,1);       // Zählt die Anzahl der Zeilenumbrüche
       If ch=' ' then
          Inc(AnzWort,1);       // Zählt die Anzahl der Leerzeichen
    end;
  end;
  CloseFile(textout);           //Schließt textout
  CloseFile(textin);            //Schließt textin
  writeln('Anzahl der Zeichen: ',AnzZeichen); // Gibt Anzahl der Zeichen aus
  writeln('Anzahl der Worte: ',AnzWort);      // Gibt Anzahl der Worte aus
  readln();
end.
Vielen Dank Whookie für diese ausführliche und hilfreiche Antwort. Jetzt bin ich schon etwas schlauer.
Wie muss ich es genau verstehen, dass writeln(textout) cr und lf schreibt und readln(textin) cr und lf ausliest und verwirft? Fungiert die Funktion als Indikator in welcher Zeile man sich gerade befindet?
Wie kann ich in einem If Statement zwei Faktoren prüfen lassen bevor ich z.B. AnzWort erhöhe? Meine Lösung ist ziemlich unschön.

Ghostwalker 30. Nov 2016 16:24

AW: Beginner: Textverarbeitung
 
writeln -> Write Line -> Schreibt eine ganze Zeile. Zeilenende wird automatisch angefügt.
readln -> Read Line -> Ließt eine ganze Zeile. Das Zeilenende wird automatisch verworfen.

Analog dazu gibts auch

write -> Schreibt n Zeichen in die Datei. Zeilenende muss selbst gehandhabt werden.
read -> Ließt n Zeichen aus der Datei. Zeilende muss selbst gehandhabt werden.


vgl. dazu auch die Ausführungen in der Delphi-Hilfe :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:30 Uhr.
Seite 1 von 2  1 2      

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