[Java] Umlaute rausfiltern / FilterReader

06/16/2012 19:45 phreeak#1
Hmm.. wusste nicht genau wie ich die Überschrift bennenen soll:
sollen für Semesterabschluss aufgabe ein Programm schreiben, dass eine txt datei einliesst, Wörter rausfiltert (Werden mittels ner Filter Klasse erstellt) damit wir sie vergleichen können, bla blubb (So ne billige "Plagiat version, wo dann ne Checksumme berechnet wird)

Jedenfalls bin ich eigentlich fertig, mir ist nur aufgefallen, dass er die Umlaute rauswirft bei meinem Buchstabenfilter (Er Filtert im Grunde alle Sonderzeichen raus. Nur Buchstaben und Zahlen werden zurück gegeben, damit man bei der Ausgabe z.B nicht "Untergang hat, sondern Untergang.)

Code:
package Plagiat;

import java.io.IOException;
import java.io.FilterReader;
import java.io.Reader;

public class FilterBuchstaben extends FilterReader {

    FilterBuchstaben(Reader in) {
        super(in);
    }

    /**
     * @see java.io.FilterReader
     */
    @Override
    public int read() throws IOException {

        int zeichen = in.read();

        if (zeichen > 255) {
            //solang bis ein zeichen erkannt wird
            zeichen = in.read();
        }
        if (zeichen == -1) {
            //Ende der Datei
            return -1;
        }
        //ruft die Methode auf um die zeichen zu filtern
        return ersetzeChar(zeichen);
    }

    public int ersetzeChar(int Char) {
        //ersetze die Buchstaben
        
        //wenn Char eine Zahl ist gib sie so zurück
        if (Character.isDigit(Char)) {
            return Char;
        }
        //wenn Char ein Großbuchstabe ist und ein Buchstabe (isLetter) 
        //wandel ihn zu einem "Kleinbuchstabe" um
        if (Character.isUpperCase(Char) && Character.isLetter(Char)) {
            return Character.toLowerCase(Char);
        }
        //wenn Char ein Kleinbuchsttabe ist und ein Buchstabe gib ihn so zurück
        if (Character.isLowerCase(Char) && Character.isLetter(Char)) {
            
            return Char;
        }
        //ansonsten gib ein Leerzeichen zurück (Falls Char ein Sonderzeichen ist)
        return 32;
    }
}

glaub hier das gleiche Problem

Code:
package Plagiat;
import java.io.IOException;
import java.io.FilterReader;
import java.io.Reader;

public class FilterWichtigesWort extends FilterReader {

    
    FilterWichtigesWort(Reader in){
        super(in);
    }
    
    
    /**
     * @see java.io.FilterReader
     */
    @Override
    public int read(char[] cbuf, int off, int len)throws IOException{
        String wort = "";
        int wortlaenge = in.read(cbuf, off, len);
        Plagiat p = new Plagiat();
        p.create_tm_unwichtigeWoerter();
        
        if(wortlaenge != -1){
            
            //Das Wort wird in einen String konvertiert um es
            //vergleichen zu können
            for(int i = 0; i < wortlaenge; i++){
                wort = wort + cbuf[i];
            }
            
            // wenn der Anfangsbuchstabe klein geschrieben ist & er ein Buchstabe ist & kein unwichtiges wort
            if (Character.isLowerCase(cbuf[0]) && Character.isLetter(cbuf[0]) && !p.pruefeAufUnwichtig(wort)) {
                //mach den Anfangsbuchstaben groß und ersetz sie in dem Char-Array.
                cbuf[0] = Character.toUpperCase(cbuf[0]);
                return wortlaenge;
            }
            
            return wortlaenge;
        }
        return -1;
    } 
}
Liegt ja sicherlich an isLetter() und das er keine Umlaute kennt sondern nur die Englischen Buchstaben? Könnte es ja mit ASCII Code machen, aber der Prof. meckert dann.

Frag mich grad wie ich das am besten lösen könne. Die Umlaute in ein Array packen und dann noch gesondert mitm if abfragen?
06/16/2012 20:12 xNopex#2
Ersetze die Umlaute doch dann beim Einlesen durch oe, ae, ... Oder ist das keine Alternative?
06/16/2012 20:13 Obilee#3
Code:
char a = 'ä';
System.out.println(Character.isLetter(a));
kommt bei mir true raus. warum übergibst du überhaupt die char werte als int ( also den uni-code ) ?
Außerdem macht es viel mehr Sinn die txt Zeilenweise auszulesen.

Code:
BufferedReader in = new BufferedReader(new FileReader("text.txt"));
		String zeile = null;
		while ((zeile = in.readLine()) != null) {
			String[] words = zeile.split(" ");
                        //jetzt jedes wort aus der zeile prüfen ob es erlaubt ist und ggf. es großschreiben lassen.
		}
06/16/2012 20:26 phreeak#4
Weil das wohl Standart ist. Auch nur so gelernt. Beim FileReader liesst man ja Zeichen für Zeichen und es kann auch ein -1 zurück gegeben werden (bedeutet dann beim in.read() dass das Ende der Datei erreicht ist)


Ja vieles macht mehr sinn, aber der Prof stellt die aufgabe ;D
06/16/2012 20:27 Obilee#5
Es ist alles andere als standart daten characterweise einzulesen und aus dennen ein wort zu baun. Du machst dir das leben unnötig schwerer.

du weißt auch ob die txt zu ende ist wenn readLine null zurück gibt ;)

edit:

Quote:
char a = 'ä';
System.out.println(Character.isLetter((int)a));
gibt ebenfalls true zurück, liegt also wohl nicht an isLetter.

gib mal ein beispiel an was gelesen wird und was nicht.

und der prof sagt in der aufgabe dass ihr das char weise einlesen müsst ?
06/16/2012 20:32 phreeak#6
Wie gesagt, ist mach die aufgaben ja nicht, dort steht drinnen, das wir es so machen sollen. Zeichenweise auslesen, 3 Filter erstellen die das Regeln und im Eigentlichen Programmablauf wird das wort aus dem cbuf[] array erstellt. (In einem Filter wird jedes Wort "vor"-erstellt und zeichenweise im Array gespeichert und die wortlänge returned, damit es später erstellt werden kann)


Wie gesagt der Prof sagt, was er will und er denkt sich wohl was dabei. Sicherlich gehts auch anders, aber dann sagta "Stimmt das geht auch so, aber wir wollten das so, weil .. BAUM." :D
06/16/2012 20:35 Obilee#7
kk,

btw:

Code:
public int ersetzeChar(int Char)
Char darfst du nicht als variablen namen nutzen, zeigt dir deine IDE es nicht als fehler an ? und welcher von den beiden code abschnitten verwendest du jetzt ?

btw2:

Code:
//wenn Char ein Kleinbuchsttabe ist und ein Buchstabe gib ihn so zurück
        if (Character.isLowerCase(Char) && Character.isLetter(Char)) {
            
            return Char;
        }
die lowercase abfrage ist hier auch sinnlos, weil an die stelle nur noch kleinbuchstaben ankommen können da alle großbuchstaben schon im ersten if abgefragt worden sind. außerdem solltest du draus ein else if machen.
06/16/2012 20:42 phreeak#8
nö Netbeans zeigt nix an. nur wenn ich char kleinschreibe. Wollte das eh noch ändern, hatte das nur grad geschrieben in ner freien Minute.

Benutze beide klasse, wird ja dadurch geregelt

Code:
 public void leseDatei() {
        try {
        ww = new FilterWichtigesWort( 
                new FilterWorteErstellen  ( 
                        new FilterBuchstaben (
                                new BufferedReader (
                                        new FileReader(parameter)))));
        } catch (FileNotFoundException e) {
            System.out.println("Datei nicht gefunden!");
        }
    }


und später im programm ablauf werden die reads angesprochen, um dann jedes Wort erstellen zu können was in cbuf steht. (Was ja im Filter dann zeichenweise jedesmal reingeschrieben wird.)

Code:
while((wortlaenge = ww.read(cbuf, 0, cbuf.length)) != -1){ 

                for(int i = 0; wortlaenge > i; i++){
                    wort = wort +cbuf[i];
                }

... Jedes Wort wird dann noch auf wichtig und unwichtig geprüft..

}
06/16/2012 20:46 Obilee#9
Code:
char a = 'ä';
		System.out.println(ersetzeChar((int)a));

public static int ersetzeChar(int Char) {
        //ersetze die Buchstaben
        
        //wenn Char eine Zahl ist gib sie so zurück
        if (Character.isDigit(Char)) {
        	System.out.println("1");
            return Char;
        }
        //wenn Char ein Großbuchstabe ist und ein Buchstabe (isLetter) 
        //wandel ihn zu einem "Kleinbuchstabe" um
        if (Character.isUpperCase(Char) && Character.isLetter(Char)) {
        	System.out.println("2");
            return Character.toLowerCase(Char);
        }
        //wenn Char ein Kleinbuchsttabe ist und ein Buchstabe gib ihn so zurück
        if (Character.isLowerCase(Char) && Character.isLetter(Char)) {
        	System.out.println("3");
            return Char;
        }
        System.out.println("4");
        //ansonsten gib ein Leerzeichen zurück (Falls Char ein Sonderzeichen ist)
        return 32;
    }
bei mir geht er in die richtigen ifs. also an der methode liegt es nicht. da er 2 bzw. 3 ausgibt.
bin jetzt fußball schaun, vllt. später bock nochmal zu schaun, die letzten 2 code abschnitte bringen mir auch nicht viel ohne zu wissen was welche variable ist bzw. vom welchen typ
06/17/2012 14:50 phreeak#10
Problem hab ich mittlerweile gelöst.

FileReader benutzt die Codierung die vom System eingestellt wird (oder von Netbeans bei properties). In meiem Fall war es UTF-8. Die Textdatei die wir auslesen sollen, war aber in ANSII Codiert. Daher führte es wohl bei den Umlauten zwischen ANSII <-> UTF-8 zu nem Fehler, so dass die Umlaute nicht erkannt wurden.

Hab die Textdatei nun in UTF-8 Codiert und nun liesst er alles ohne Probleme aus.
06/17/2012 21:45 Obilee#11
kk dann mach ich mal zu.

#closed