Dienstag, 29. November 2011

Entfernen von Worten aus Textdateien / Removing words from textfiles

Visual FoxPro stellt uns nicht nur eine Menge Funktionen zur Stringmanipulation zur Verfügung. Auch das Öffnen und Bearbeiten von Dateiinhalten kann auf mehreren Wegen durchgeführt werden.

Wollen wir bspw. bestimmte Worte (oder Zeichenfolgen) aus einer Textdatei entfernen, so können wir die Datei natürlich über die Funktionen FOPEN(), FGETS(), FWRITE() und FCLOSE() verarbeiten, mit Hilfe von FILETOSTR() und STRTOFILE() funktioniert dies jedoch erheblich einfacher.

Über FILETOSTR() lesen wir den Inhalt einer Datei komplett in eine Variable die wir anschliessend gezielt bearbeiten und mit STRTOFILE() wieder auf die Festplatte schreiben können.

Im Blogeintrag zur Manipulation von MP3 ID3v1 Tags arbeite ich ebenfalls mit diesen beiden Funktionen, allerdings wird dort ein kompletter Bereich des Datenstroms verändert.

lcFile = [D:\Temp\test.txt]
lcFileContent = FILETOSTR( lcFile )

* Do something

STRTOFILE( lcFileContent , lcFile )

Zur Verarbeitung des Datenstroms welcher sich nun in der Variablen 'lcFileContent' befindet, stehen uns zwei Funktionen zur Verfügung, von denen die eine ( OCCURS() ) die Häufigkeit des Auftretens der zu entfernenden Zeichenkette aufzeigt und die andere ( STRTRAN() ) den Austausch bzw. das Entfernen vornimmt.

Im nun folgenden Codebeispiel wird zunächst eine Testdatei erzeugt und anschliessend wieder eingelesen, das Auftreten der Zeichenfolge 'Lorem ipsum' geprüft und das zweite Auftreten aus dem Datenstrom entsorgt. Anschliessend wird die Datei aktualisiert.



* // Schritt 1: Demodaten erzeugen
* // Step 1   : Creating demo data
LOCAL    lcFileName as String , lcString as String , lcFileContent as String , ;
        lcSafety as String
lcFileName    = [D:\Temp\test.txt]
lcSafety    = SET( [Safety] )
SET SAFETY OFF 

* // Der Beispieltext enthält insgesamt 4x die Zeichenfolge 'Lorem ipsum'
* // This demo data contains 4x the character string 'Lorem ipsum'
TEXT TO lcString TEXTMERGE NOSHOW PRETEXT 2+4
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, 
    sed diam nonumy eirmod tempor invidunt ut labore et dolore 
    magna aliquyam erat, sed diam voluptua. At vero eos et 
    accusam et justo duo dolores et ea rebum. Stet clita kasd 
    gubergren, no sea takimata sanctus est Lorem ipsum dolor 
    sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing 
    elitr, sed diam nonumy eirmod tempor invidunt ut labore et 
    dolore magna aliquyam erat, sed diam voluptua. At vero eos 
    et accusam et justo duo dolores et ea rebum. Stet clita 
    kasd gubergren, no sea takimata sanctus est Lorem ipsum 
    dolor sit amet.
ENDTEXT 
STRTOFILE( lcString , lcFileName )

* // Schritt 2: Einlesen der erzeugten Testdatei
* // Step 2   : Reading the created textfile
lcFileContent = FILETOSTR( lcFileName )

* // Schritt 3: Feststellen der Häufigkeit des Auftretens von 'Lorem ipsum'
* // Step 3   : Checking the frequency of occurrence of 'Lorem ipsum'
CLEAR 
? [Lorem ipsum was found ]
?? OCCURS( [Lorem ipsum] , lcFileContent )
?? [ times within the filestream]

* // Schritt 4: Entfernen des zweiten Auftretens von 'Lorem ipsum'
* // Step 4   : Removing the second occurance of 'Lorem ipsum'
lcFileContent = STRTRAN( lcFileContent , [Lorem ipsum] , [] , 2 , 1 )

* // Schritt 5: Aktualisieren der Datei auf der Festplatte
* // Step 5   : Updating the file on harddisk
STRTOFILE( lcFileContent , lcFileName )

SET SAFETY &lcSafety

RELEASE lcFileName , lcString , lcFileContent , lcSafety

Freitag, 25. November 2011

Datumsspielereien (Teil 7) / Date gadgets (Part 7)

Im Folgenden eine kleine Abwandlung der Routine aus Teil 6 in der es um die Berechnung des letzten Sonntags eines Monats ging.
Wollen wir nicht den letzten Sonntag sondern einfach nur den letzten Tag des Monats berechnen, so ist es am einfachsten zunächst das Datum des 1. Tages des Folgemonats zu berechnen und davon einfach einen Tag abzuziehen. Ähnlich funktioniert auch die Methode aus Teil 6.
Hier nun der Mustercode:

CLEAR 

?GetLastDayOfMonth( DATE() )
?GetLastDayOfMonth( {12.02.2012} )

FUNCTION GetLastDayOfMonth as Date 
LPARAMETERS vDate as Date

    RETURN DATE( YEAR( GOMONTH( vDate , 1 ) ) , MONTH( GOMONTH( vDate , 1 ) ) , 1 ) - 1

ENDFUNC 

Dienstag, 8. November 2011

Arbeiten mit Ganzzahl und Kommazahlen / working with integers and decimals

Für die Arbeit mit Ganz- und Kommazahlen stellt uns Visual Foxpro ein paar Funktionen zur Verfügung, mit deren Hilfe wir Vorzeichen sowie Vor- und Nachkommastellen extrahieren können. Je nach Aufgabenstellung sind diese Funktionen recht hilfreich.

Im einzelnen dreht es sich um die folgenden Funktionen: INT(), ABS(), CEILING(), FLOOR() und MOD().

Der folgende Mustercode soll die Arbeitsweise der hier vorgestellten Funktionen veranschaulichen. Als Basis dient eine negative Kommazahl. Dies ermöglicht das Aufzeigen evtl auftretender Fallstricke. Natürlich nur für den Fall, das wir vergessen haben sollten, wie mit negativen Zahlenwerten umgegangen wird.... ;-)

An dieser Stelle noch ein Verweis auf einen älteren Blogeintrag zum Thema Modulo-Berechnungen, der dies hier ganz gut ergänzt:
http://tomsvfpblog.blogspot.com/2007/12/wieso-verhlt-sich-die-modulo-funktion.html

CLEAR 
lnNumeric = -123.456
?[Original                   :]
??lnNumeric

* Entfernen der Nachkommastellen / remove decimal places            
?[INT( lnNumeric )           :]
??INT( lnNumeric )

* Vorzeichenlose Ganzzahl / unsigned integer                        
?[ABS( lnNumeric )           :]
??ABS( lnNumeric )

* Nächst höhere Vorzeichen-Ganzzahl / next higher signed integer    
?[CEILING( lnNumeric )       :]
??CEILING( lnNumeric )

* Nächst niedrigere Vorzeichen-Ganzzahl / next lower signed integer    
?[FLOOR( lnNumeric )         :]
??FLOOR( lnNumeric )

* extrahieren der Nachkommastellen / extracting decimal places        
?[MOD( lnNumeric , 1 )       :]
??MOD( lnNumeric , 1 )

* Nächst höhere Ganzzahl / next higher integer                        
?[CEILING( ABS( lnNumeric ) ):]
??CEILING( ABS( lnNumeric ) )

* Nächst niedrigere Ganzzahl / next lower integer                    
?[FLOOR( ABS( lnNumeric ) )  :]
??FLOOR( ABS( lnNumeric ) )

* extrahieren der Nachkommastellen / extracting decimal places        
?[MOD( ABS( lnNumeric ) , 1 ):]
??MOD( ABS( lnNumeric ) , 1 )