Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Zahlen aus Textdatei lesen und in Konsole ausgeben
Ich versuche seit geraumer Zeit das folgende Problem zu lösen:
Ich möchte eine Textdatei einlesen die nur Zahlen beinhaltet und in etwa so ausschaut:
23 45 56 68 90
34 44 56 78 98
34 44 55 67 77
Danach möchte ich einfach die Zeilennummer und Spaltennummer eingeben (einfach mit System.out.println()) und
die Zahl in der Konsole anzeigen lassen: z.B.: i=2; j=4; und das Ergebniss=78;
Ich habe das Programm in 3 Schritte unterteilt:
1. Lade die Zahlen aus dem Textfile in den String[][] array (Klassenvariable)
2. Kontrolliere array, drucke ihn auf der Konsole aus
3. Teste den array auf verschiedenen Positionen
Code:
import java.io.*;
import java.text.*;
import java.util.*;
import java.lang.String;
public class Dateieinfuegen_1 {
// Dies ist das Array, in das die Zahlen gespeichert werden
static String[][] array = new String[10][];
public static void main (String[] args) {
importFile(); // Schritt 1
System.out.println("Kontrolle: "); // Schritt 2
printArray();
// Teste array: // Schritt 3
System.out.println("\nZwei erfolgreiche Tests:");
System.out.println("i= 2, j=4 ergibt: "+getValue(2,4));
System.out.println("i= 1, j=1 ergibt: "+getValue(1,1));
System.out.println("\nZwei gescheiterte Tests:");
System.out.println("i= 8, j=1 ergibt: "+getValue(8,1));
System.out.println("i=11, j=0 ergibt: "+getValue(11,0));
} // en main
static void importFile() {
/*
* Liest die Datei ein und speichert sie in den String[][] array
*/
try{
BufferedReader reader = new BufferedReader(new FileReader("textdatei.txt"));
String line;
for(int i = 0; (line = reader.readLine()) != null; i++) {
array[i] = line.split(" ");
}
reader.close();
} // end try
catch(FileNotFoundException ex){
System.out.println("File nicht gefunden");
} // end catch
catch(IOException ex){
System.out.println ("Lesefehler");
} // end catch
catch (IndexOutOfBoundsException ex) {
System.out.println("ups, der String[][] array ist zu klein für diese Textfilegroesse");
System.out.println("maximal sind "+array.length+" Zeilen moeglich, sonst muss die Groesse von array in Zeile 9 erhoeht werden");
System.exit(1);
} // end try
} // end importFile
static void printArray() {
/*
* Druckt das Array in der Konsole aus. Die Funktion ist nicht wunderschön geschrieben,
* weil wenn der String[][] array nicht gefüllt ist (also wenn array[array.length][]==null),
* wird die Schleife aufgrund einer NullPointerException abgebrochen
*/
int i=0;
try {
String[] arrayLine;
while (i<array.length) {
arrayLine = array[i++];
for (int j=0;j<arrayLine.length;j++) {
System.out.print(arrayLine[j]+" ");
} // end for j
System.out.println("");
} // end while
} //end try
catch (NullPointerException ex) {
// Das Ende der Daten in array ist erreicht
// tue nichts
} // end catch
} // end printArray
static String getValue(int line, int pos) {
/*
* Gibt die Zahl an der gewünschten Stelle zurück, wobei die Zahl ganz oben links die
* Koordinaten (1,1) besitzt.
*/
try {
return array[line-1][pos-1];
} // end try
catch (NullPointerException ex) {
/*
* An dieser Stelle ist keine Zahl gespeichert
*/
return "keine Zahl gespeichert";
} // end catch
catch (IndexOutOfBoundsException ex) {
/*
* Die Koordinaten (line,pos) sind im String[][] array nicht voranden
*/
return "Ausserhalb des Arrays";
}
}
} // end class dateieinfuegen
Was man noch verbessern könnte, ist die Grösse von Array. Es wäre natürlich schöner, wenn array genau so gross wäre, wie es auch sein müsste und keine uninitialisierten Stellen mehr aufweisen würde. Dazu müsste man aber vor der Instanzierung die Anzahl Zeilen des Textfiles wissen. Falls dieses TextFile als Speichermedium für eine Matrix diente (wofür es zwar einfachere Methoden gäbe), könnte man vor dem speichern der Matrix in dieses Textfeldes auf die erste Zeile die Anzahl Zeilen schreiben und dann die Matrix anfügen.
Im Übrigen ist es nicht notwenig, dass jede Zeile gleich viele Werte beinhaltet.
23 45 56 68 90
34 98
34 55 67 77
als Textfile wäre kein Problem.
Frage 1:
Wenn du die Zahlen aus der Datei mathematisch behandeln willst, musst du sie in Integer Werte parsen.
Code:
String str23 = getValue(2,3);
int value23 = Integer.parseInt(str23);
dann ist value23 der Wert an Stelle (2,3) und die kannst damit rechnen oder sie verwenden, wie du willst.
Frage 2:
Die IndexOutOfBoundsException tritt auf, weil der String[][] array zu klein für 30 Zeichen ist. Dies kannst du in meinem Code in Zeile 9 ändern. Dort gibst du einfach so viel ein, wie nötig ist.
Mit einer Matrix habe ich eigentlich genau ein solches Objekt wie Array gemeint. Natürlich bin ich nicht umfassend vertraut mit deiner Aufgabe, aber für mich sieht es so aus, als würdest du irgend ein Programm laufen lassen und zum Schluss diese Zahlen abspeichern müssen, damit du sie beim nächsten Mal wieder verwenden kannst.
Sollte dies der Fall sein, gäbe es in der Tat eine einfachere Möglichkeit, diese Zahlen zu speichern und wieder zu importieren, nämlich indem du einfach das array auf die Festplatte abspeicherst.
Der Nachteil ist, du kannst diese Datei dann nicht einfach mit einem Editor öffnen und den Inhalt betrachten. Wenn du das brauchst, musst du das wie anhin machen.
Ein array zu speichern ist keine grosse Sache:
Code:
import java.io*;
// Das ist dein Array, das du für dein Programm brauchst
int[][] array;
public void saveFile() {
/*
* Diese Methode speichert dein int[][] array auf die Festplatte
*/
try {
// Erstellen des Outputstreams auf die Festplatte
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("myArray.arr"));
// speichern des int[][] array auf die Festplatte
output.writeObject(array);
output.close();
} // end try
catch (IOException ex) {
System.out.println("Irgendwas ist schief gegangen");
ex.printStackTrace();
} // end catch
}
Das Importieren funktioniert dann folgenderweise:
Code:
import java.io.*;
int[][] array;
public void importFile() {
/*
* Diese Methode liesst die Datei myArray.arr ein und speichert sie auf das int[][] array
*/
try {
// Erstellen des InputStreams von der Festplatte
ObjectInputStream input = new ObjectInputStream(new FileInputStream("myArray.arr"));
// Einlesen des Objekts -> Typencasting in int[][]* -> speichern auf array
array = (int[][]) input.readObject();
input.close();
} // end try
catch (ClassNotFoundException ex) {
System.out.println("Klasse nicht gefunden");
ex.printStackTrace();
}
catch (FileNotFoundException ex) {
System.out.println("Das File wurde nicht gefunden");
ex.printStackTrace();
} // end catch
catch (IOException ex) {
System.out.println("Fehler beim einlesen");
ex.printStackTrace();
} // end catch
}
*readObject liefert ein Objekt vom Typ Object, da es ja nicht einfach so weiss, dass hier ein int[][] kommt. Deshalb wird int[][] voran in Klammern gesetzt, damit das Objekt, dass hier kommt in ein int[][] umgewandelt wird.
Ich hoffe, der Code stimmt, ich bin zur Zeit verhindert ihn selbst zu kompilieren. Aber ich denke, du kannst daraus entnehmen, ob dies eine Alternative Speichermethode für dich wäre.
Es ist hier auch noch möglich, weitere Objekte zu speichern, einfach nach output.writeObject(xyz) noch weitere solche Befehle anhängen. Bei primitiven Datentypen gäbe es dann auch noch output.writeInt(abc) etc. In der gleichen Reihenfolge kannst du die Objekte dann auch wieder einlesen und beim nächsten Programmstart verwenden.
@java2000
Ist ja toll wenn du ihr/ ihm hier alles so praesentierst, und sie/ er hat kaum was zu tun, ausser copy& paste.
Aber meinst du net das sie/ er dadurch gar nix lernt? Man lernt odch am besten, wenn man sich selbst mit dem problem auseinandersetzt. Meine Meinung. Einfach Quellcode zu kopieren, bringt net viel mehr ausser das dasProgramm funktioniert, aber gelernt hat man nix.
andererseits sind das festgefahrene Folgen von Bibliotheksaufrufen,
die kann man eh nicht selber lernen,
das beste wäre noch, die selber in einem Lehrbuch zu finden und von dort zu kopieren,
schon mit der API sind solche komplexen Dinge für einen Anfänger fast nicht zu finden,
selber lernen kann man eher beim Schreiben eines Sortieralgoritmusses oder ähnliches,
wo alle Syntax da ist und man nur noch logisch denken und richtigen Code bauen muss,
Datei-Einlesen mit Exception-Handling ist was ganz anderes
dem kann ich nicht unbedingt zu stimmen - ich bin in Sachen Java-Programmierung auch Anfänger und ich muss auch Daten aus einer Datei einlesen und diese weiterverarbeiten. Man muss etwas Geduld haben und kann anhand bestimmter Tutorials doch schon viel finden und wenn man Fragen hat dann fragt man - aber wenn man mir jetzt kompletten Quellcode hingelegt hätte und der hätte funktioniert - wo probiert man denn dann noch herum.
Das einlesen von ner Datei kann man sich raussuchen, und dann kann man sich raussuchen wie man ne Zeile ausliest, und dann wie man sachen in ein Array schreibt. Bzw mit der Angabe 2dimensionales Array hatte sie/ er sich was raussuchen koennen.
@SlaterB
Ich gebe dir teilweise Recht, er würde wohl mehr lernen, wenn ich ihm nur die Klasse ObjectOutputStream hingeworfen hätte, allerdings hätte er dann auch einen viel grösseren Aufwand. Ich glaube, die Kommentare sorgen für ein gutes Verständnis des Codes und schlussendlich sehe ich es als jedermans Eigenverantwortung, ob er/sie etwas suchen, fragen oder lernen möchte.
Nur anfaenger, nehmen sowas net so ernst, und kopiern erstmal und lesen sich auch net die KOmmentare durch, oder nur teilweise. Natuerlich waere ihr/ sein aufwand um einiges groesser gewesen, haettest du das net alles hingeschrieben, aber sie/ er haette um einiges mehr gelernt.
Ich finde es schlimm wie einige versuchen ihr Anfängern nicht zu helfen.
Es wird extra viel verschleiert und einem nix genau gesagt. WIe soll man denn dann lernen ?
Ich habe das Gefühl einige haben Angst und wollen nicht, dass einer jetzt von guten Leuten etwas lernen kann.
Ich finde es sehr gut, dass einer auch mal richtige Lösungen zeigt wie es geht.
ICh danke den die wirklich Leuten helfen wollen und nicht immer auf Java ist auch eine Insel verweisen.
Ich finde es schlimm wie einige versuchen ihr Anfängern nicht zu helfen.
Es wird extra viel verschleiert und einem nix genau gesagt. WIe soll man denn dann lernen ?
Ich habe das Gefühl einige haben Angst und wollen nicht, dass einer jetzt von guten Leuten etwas lernen kann.
Ich finde es sehr gut, dass einer auch mal richtige Lösungen zeigt wie es geht.
ICh danke den die wirklich Leuten helfen wollen und nicht immer auf Java ist auch eine Insel verweisen.
> Ich habe das Gefühl einige haben Angst und wollen nicht, dass einer jetzt von guten Leuten etwas lernen kann.
richtiger ist: einige wollen nicht unnötig Zeit verschwenden, den Anfängern alles zu erklären, was woanders schon steht
+ denjenigen auch noch das Selber-lernen abgewöhnen
(doppelt schlecht)
> ICh danke den die wirklich Leuten helfen wollen und nicht immer auf Java ist auch eine Insel verweisen.
> Da ist oft was total beschissen erklärt.
richtiger ist: meist machen sich die Anfänger gar nicht die Mühe, dort intensiv nachzulesen,
wer in korrekten ausführlichen Deutsch genau erklärt, was er/ sie an einem Thema/ Satz/ Beispiel in einem Lehrbuch nicht versteht,
sich also sichtbar Mühe gibt, bekommt auch garantiert eine schöne Antwort,
wer aber blind 'ich verstehe nix' schreibt, also aller Wahrscheinlichkeit nach keine eigene Arbeit hineinsteckt,
der kann auch keine ausführlichen Individualantworten erwarten
@Gast
Natuerlich will ich das Anfaengern geholfen wird. Nur durch komplette Loesungen hilft das nix!!! Man lernt nunmal am besten wenn man rumprobiert. Durch Loesungsansaetze oder durch erklaerungen kommt man auch oft sehr weit.
Sorry wenn es fuer so rueberkommt als wolle ich nicht das dir jemand hilft
Ich habe nochmal nach der Lösung gesucht. Ich glaube hier helfen keine Bücher, hier ist Erfahrung gefragt.
1.) Es werden nicht immer die richtigen Zahlen aus der Matrix gelesen, vor allem wenn die Datei, in meinem Fall 50 Zeilen und 5 Spalten hat. Zb.: getValue(20,2) zeigt getValue(18,2);
2.) Parsen geht nicht. Ich habs auf mehrere Arten probiert. Nur verschiedene Fehlerausgaben (am häufigsten NumberFormatException);
3.) Der code kompiliert und gibt nur Strings aus. Gott sei Dank, zumindest das!
Code:
import java.io.*;
import java.text.*;
import java.util.*;
import java.lang.*;
public class Dateieinfuegen_5 {
// Dies ist das Array, in das die Zahlen gespeichert werden
static String[][] array = new String[1000000][];
public static void main (String[] args) {
importFile(); // Schritt 1
System.out.println("Kontrolle: "); // Schritt 2
printArray();
// Teste array: // Schritt 3
System.out.println("\nZwei erfolgreiche Tests:");
System.out.println("i= 3, j=4 ergibt: "+getValue(3,4));
System.out.println("i= 3, j=2 ergibt: "+getValue(3,2));
System.out.println("\nZwei gescheiterte Tests:");
System.out.println("i= 8, j=1 ergibt: "+getValue(8,1));
System.out.println("i=11, j=0 ergibt: "+getValue(11,0));
System.out.println(" ");
System.out.println("Berechnungen");
String str34 = getValue(3,4);
//int[][] value34;
//value34 =new int[4][4];
//value34 [3][4] = Integer.parseInt(str34); // So gibt es zumindest eine str34 Ausgabe aber
//kein parsen
//int value34 = Integer.parseInt(str34); // So aber gibt es keine str34 Ausgabe
String str12 = getValue(1,2);
//int value12 = Integer.parseInt(str12);
String str101 = getValue(10,3); //Da gibt er den falschen Wert zurück.
System.out.println(" ");
System.out.println("Ausgabe mit getValue(3,4)");
System.out.println(" i=3"+" " +"j=4"+" "+"="+(getValue(3,4)));
System.out.println(" ");
System.out.println("Ausgabe mit strXX");
System.out.println("i=3"+" "+"j=4"+""+"="+str34);
System.out.println("i=1"+" "+"j=2"+" "+ "="+str12);
System.out.println("i=10"+" "+"j=1"+" "+"="+str101);
System.out.println(" ");
System.out.println("Ausgabe mit value34=Integer.parseInt(str34)");
System.out.println("i=3"+" "+"j=4"+" "+"="+value34); //Das funktioniert nicht?
//System.out.println("i=1"+" "+"j=2"+" "+"="+value12);
} // end main
static void importFile() {
/*
* Liest die Datei ein und speichert sie in den String[][] array
*/
try{
BufferedReader reader = new BufferedReader(new FileReader("textdatei.txt"));
String line;
for(int i = 0; (line = reader.readLine()) != null; i++) {
array[i] = line.split(" ");
}
reader.close();
} // end try
catch(FileNotFoundException ex){
System.out.println("File nicht gefunden");
} // end catch
catch(IOException ex){
System.out.println ("Lesefehler");
} // end catch
catch (IndexOutOfBoundsException ex) {
System.out.println("ups, der String[][] array ist zu klein für diese Textfilegroesse");
System.out.println("maximal sind "+array.length+" Zeilen moeglich, sonst muss die Groesse von array in Zeile 9 erhoeht werden");
System.exit(1);
} // end try
} // end importFile
static void printArray() {
/*
* Druckt das Array in der Konsole aus. Die Funktion ist nicht wunderschön geschrieben,
* weil wenn der String[][] array nicht gefüllt ist (also wenn array[array.length][]==null),
* wird die Schleife aufgrund einer NullPointerException abgebrochen
*/
int i=0;
try {
String[] arrayLine;
while (i<array.length) {
arrayLine = array[i++];
for (int j=0;j<arrayLine.length;j++) {
System.out.print(arrayLine[j]+" ");
} // end for j
System.out.println("");
} // end while
} //end try
catch (NullPointerException ex) {
// Das Ende der Daten in array ist erreicht
// tue nichts
} // end catch
} // end printArray
static String getValue(int line, int pos) {
/*
* Gibt die Zahl an der gewünschten Stelle zurück, wobei die Zahl ganz oben links die
* Koordinaten (1,1) besitzt.
*/
try {
return array[line-1][pos-1];
} // end try
catch (NullPointerException ex) {
/*
* An dieser Stelle ist keine Zahl gespeichert
*/
return "keine Zahl gespeichert";
} // end catch
catch (IndexOutOfBoundsException ex) {
/*
* Die Koordinaten (line,pos) sind im String[][] array nicht vorhanden
*/
return "Ausserhalb des Arrays";
}
} // end getValue
} // end class Dateieinfuegen5
Martin, du hast Recht ich muss die Dateien speichern aber das erste Mal muss ich eine Datei reinladen und die Zahlen bearbeiten, dann kann ich mit ZwischenSpeichern leichter mit der Matrix umgehen.