Input/Output 2 Textdateien mit einander vergleichen

Fufonfuul

Mitglied
Hallo Allerseits 🙂
bin Informatikstudent im 1. Semester und und soll ein Programm schreiben welches Textdateien zeilenweise miteinander vergleicht. Sitzte da schon mehrere Stunden dran aber weiß nicht genau wie ich die Fehler beheben kann.

Hier ist mal mein bereits geschriebener Code:

Java:
import java.io.*;
import java.util.*;

public class Diff {   
    public static void main(String[] args) throws FileNotFoundException {
        diff();
    }

    public static void diff() {
        Scanner datei1=null, datei2=null;
        String text1, text2;
        int zeile = 0;
        try {
            datei1 = new Scanner(new File("text1.txt"));
            datei2 = new Scanner(new File("text2.txt"));
            do {                           
                text1 = datei1.nextLine();
                text2 = datei2.nextLine();
                zeile++;               
                if (text1.compareTo(text2) <0 | text1.compareTo(text2) >0)  {
                    System.out.println("Zeile "+zeile+":");
                    System.out.println("< "+text1);
                    System.out.println("> "+text2);
                    System.out.println();                                                     
                }else {
                    continue;
                }           
            } while (datei1.hasNextLine() && datei2.hasNextLine());
           
        }catch (FileNotFoundException notFound) {
            System.out.println("Datei nicht gefunden");
            return;
        }catch (NoSuchElementException noLine) {
            System.out.println("Eine der Dateien ist zu lang"); /** tritt ein falls eine der Dateien
                                                         länger als die andere ist*/
            return;
        }finally {
            if (datei1 !=null) datei1.close();
            if (datei2 !=null) datei2.close();
        }
    }           
}

Der Code soll mir die Zeilennummer ausgeben wo sich die Zeilen in Datei 1 und 2 unterscheiden, so etwa in diesem Muster :
Zeile xy:
< String hier so
> String hier anders

So weit so gut, das Ding ist aber, dass sobald eine Datei mehr Zeilen hat als die andere sollen diese als leere Zeilen gewertet werden und dementsprechend wieder mit der anderen Datei verglichen werden. habe schon viele Lösungen gesehen die "BufferedReader" verwenden, leider soll ich diesen nicht verwenden. Ich hoffe ihr habt meine Frage verstanden und könnt mir helfen 😀
lg
 
BufferedReader braucht man dafür nicht, das klappt ganz wunderbar mit Scanner.

Du musst es nur so umbauen, dass du nicht einfach immer von beiden Dateien die nächste Zeile liest, sondern nur jeweils von einer Datei, wenn diese noch weitere Zeilen hat (wie du das prüfst, hast du bereits verwendet), und wenn sie keine Zeilen mehr hat, musst du mit einem sinnvollen Default-Wert weiter arbeiten.

Anders als du es aktuell tust, muss die Schleife dann so lange laufen, wie eine Datei noch weitere Zeilen hat.
 
Von Scanner würde ich abraten, ungeeignetes Werkzeug dafür, davon es selber zu schreiben auch. Es gibt Tools genau dafür.

Die Frage ist was mit zusätzlichen Zeilen welche in einer aber in der anderen Datei nicht vorkommen geschehen sollen.
 
Leider ist es eine Aufgabe für meine Hochschule und ich soll mit dem Scanner vorgefertigete Dateien einlesen lassen. Ich versuche mich gerade an den Vorschlag von mrBrown und versuche }else if statements einzubauen falls eine der Dateien keine Zeile mehr zum einlesen hat (habe den Vorschlag zumindest so interpretiert) und die "kürzere" Datei dann schließt.
 
Ok es ist schwer als ich erwartet habe oder ich stelle mich gerade etwas dämlich an, bin leider noch frisch was das Programmieren angeht >.<
Der Compiler spuckt mir ne Fehlermeldung aus:

Diff.java:29: error: cannot find symbol
}else if (text1.hasNext() ==false) {
^
symbol: method hasNext()
location: variable text1 of type String

Java:
 }else if (text1.hasNext() ==false) {
                    datei1.close();
                    System.out.println("Zeile "+zeile+":");
                    System.out.println("< ");
                    System.out.println("> "+text2);
                    System.out.println();
 }
Kann ich die Condition überhaupt so deklarieren?(offensichtlich nicht sonst würde der Compiler keine Fehlermeldung ausgeben)
 
Kann ihr gerne nochmal posten aber viel geändert ist daran nichts im Vergleich zu oben. Der einzige Unterschied sind sind die }else if Statements wenn eine der Dateien größer ist als die andere und ich habe die Condition für die do/while Schleife etwas angepasst (dank Hinweis von mrBrown)
Java:
import java.io.*;
import java.util.*;

public class Diff {   
    public static void main(String[] args) throws FileNotFoundException {
        diff();
    }
   
    public static void diff() {
        Scanner datei1=null, datei2=null;
        String text1, text2;
        int zeile = 0;
        try {
            datei1 = new Scanner(new File("text1.txt"));
            datei2 = new Scanner(new File("text2.txt"));
            do {                           
                text1 = datei1.nextLine();
                text2 = datei2.nextLine();
                zeile++;               
                if (text1.compareTo(text2) <0 | text1.compareTo(text2) >0)  {
                    System.out.println("Zeile "+zeile+":");
                    System.out.println("< "+text1);
                    System.out.println("> "+text2);
                    System.out.println();                                                     
                }else if (text1.hasNext() ==false) {
                    datei1.close();
                    System.out.println("Zeile "+zeile+":");
                    System.out.println("< ");
                    System.out.println("> "+text2);
                    System.out.println();
                }else if (text2.hasNext() ==false) {
                    datei2.close();
                    System.out.println("Zeile "+zeile+":");
                    System.out.println("< "+text1);
                    System.out.println("> ");
                    System.out.println();
                }else {
                    continue;
                }
            } while (datei1.hasNextLine() | datei2.hasNextLine());               
        }catch (FileNotFoundException notFound) {
            System.out.println("Datei nicht gefunden");
            return;
        }catch (NoSuchElementException noLine) {
            System.out.println("Eine der Dateien ist zu lang");
            return;       
        }finally {
            if(datei1 !=null) datei1.close();
            if(datei2 !=null) datei2.close();
        }
    }           
}
 
Die Änderung beschreibt noch nicht 100%ig das, was @mrBrown oben beschrieben hatte. Du liest ja trotzdem bei jeder Iteration von beiden Dateien eine Zeile ein (was sicherlich zu einer Exception führt, weil du ggf. den Stream vorher schließt mit datei.close().

Zu deinem eigentlichen Problem: schau mal genau, auf welchem Objekt du gerade hasNext() aufrufst. text1 bzw text2 sind Strings - keine Scanner. 🙂

Off-Topic: Gewöhn' dir an für boolsche Vergleiche || zu nutzen. | nutzt man i.d.R. nur für Bit-Operationen. (würde aber in dem Fall keinen Unterschied machen).
 
Machst Du so 🙂
Java:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @Date 05.12.2018
 */
public class Diff {

    public static void main(String[] args) {
        String a = "bla1\n"
                + "bla2\n"
                + "bla3\n"
                + "bla4\n"
                + "bla5";
        String b = "bla4\n"
                + "bla4\n"
                + "bla4\n"
                + "bla4\n"
                + "bla4\n"
                + "bla1\n"
                + "bla2\n"
                + "bla9\n"
                + "bla4\n"
                + "bla5";

//        String zwischen = a;
//        a = b;
//        b = zwischen;

        List<String> c = new ArrayList<>();
        List<String> d = new ArrayList<>();
        try (Scanner e = new Scanner(a); Scanner f = new Scanner(b)) {
            while (e.hasNextLine()) {
                c.add(e.nextLine());
            }
            while (f.hasNextLine()) {
                d.add(f.nextLine());
            }
        }
        List<String> g = new ArrayList<>();
        List<String> h = new ArrayList<>();
        for (int i = 0; i < c.size(); i++) {
            for (int j = i; j < d.size(); j++) {
                if (c.get(i).equals(d.get(j))) {
                    g.add(c.get(i) + " " + d.get(j) + " " + i + " " + j);
                    break;
                }
            }
        }
        for (int i = 0; i < d.size(); i++) {
            for (int j = i; j < c.size(); j++) {
                if (d.get(i).equals(c.get(j))) {
                    h.add(d.get(i) + " " + c.get(j) + " " + i + " " + j);
                    break;
                } else {
                    // ?
                }
            }
        }
        if (g.size() >= h.size()) {
            g.stream().forEach(System.out::println);
        } else {
            h.stream().forEach(System.out::println);
        }
    }

}
 
Vielen dank für diesen wertvollen Tipp. Hilft mir wirklich sehr auf sowas hinzuweisen
Naja, der Compiler sagt Dir genau, wo das Problem liegt. Was soll man dazu noch großartig sagen? Falsche Variable verwendet.

Dein Code am Anfang war ja fast fertig. Die Anpassung ist trivial: Du musst vor dem Einlesen der jeweiligen Zeile einfach abprüfen, ob es weitere Daten gibt.

Java:
String line1 = "";
if (datei1.hasNextLine()) {
    line1 = datei1.nextLine();
}
liefert die nächste Zeile aus der Datei oder "", wenn es keine solche gibt.

Ansonsten musst Du im while nur die Verknüpfung zu einem OR ändern - hast Du bereits gemacht. Ich würde aus der do-while auch eine while-Schleife machen.
 

Zurück
Oben