# tabelle



## mermen (6. Apr 2006)

hi!
ich habe folgendes problem!

wenn ich in einer tabelle alles strukturiert untereinander haben möchte z.b.:

pos    name    vorname    strasse    
1        kurt      maier        musterstrasse
2        hans     schulze      taubenweg


und es einzelne strings sind, die ich hintereinander einlese, wie mach ich das am besten???

hat da einer einen guten vorschlag???


----------



## Leroy42 (6. Apr 2006)

1) Meinst du eine JTable? Oder eine einfache JTextArea?
2) Von wo aus liest du die Daten ein? Aus einer Datei? Wie ist dessen Struktur? Kannst du Sie selbst definieren?

Bitte etwas ausführlicher.


----------



## mermen (6. Apr 2006)

naja...ich glaube Jtabellen sind grafisch...oder???...kenne die gar nicht!!!

also ich möchte eine einfache textausgabetabelle!!!

ich lese aus einer textdatei ein und möchte sie dann auch mit eventuellen weiteren eintragen zurück speichern!

ja, definieren kann ich sie selbst!


----------



## The_S (6. Apr 2006)

Wenn nicht grafisch wie dann? Auf der Konsole? Oder virtuell in deinem Programm ohne dass der User davon Wind bekommt?


----------



## mermen (6. Apr 2006)

textbasierend auf der konsole!


----------



## The_S (6. Apr 2006)

Du liest zuerst alles ein, schaust was das längste Wort ist und füllst dann alle Wörter mit leerzeichen auf, bis sie die Länge des längsten Wortes haben (oder am Besten noch ein paar mehr, sonst klebt alles so aneinander). Kannste auch spaltenweiße machen.

Evtl. könnteste auch ein wenig mit tabs arbeiten, aber wenn die Worte in der Länge sehr unterschiedlich sind is das keine 100% sichere Lösung.

Was anders fällt mir jetzt spontan auch net ein  :bahnhof:


----------



## mermen (6. Apr 2006)

kann ich denn irgentwie bestimmen, an welcher stelle der string beginnen soll?
also, das ich sage, name fängt an stelle 5 und vorname an stelle 15 an!??? ich habe bis jetzt nur bestimmt, wie lang die variablen maximal sein dürfen! also ist der name beispielsweise nicht länger als 15 zeichen! aber natürlich könnte er auch kürzer sein....


----------



## Leroy42 (6. Apr 2006)

1. Definier dir eine einfache CSV-Datei:

1§Karl-Otto&Schmidt&Kleiner Weg 9
2§Berta&Panislovski&Klavierstr. 42

2. Lies diese Zeilenweise ein, splitte die Strings anhand des Zeichens *§* und schreibe die
Daten in ein String[][]

3. Bestimme die jeweils längsten Spaltenbreiten pro Spalte

4. Gib die Daten entsprechend dieser Spaltenbreiten aus.


----------



## mermen (6. Apr 2006)

naja....die spaltenbreite sollte sich nicht verändern...weil ja eventuell nur ein eintrag hinzugefügt wird....

also, die tabelle soll nun keine adressliste sein, sondern eine highscore!

die überschrift gebe ich in einer einfachen zeile vor:

rang      Name         punkte           prozent


das einzige was variable ist, ist der name....aber der soll eine breite von 15 zeichen betragen!
wenn der name natürlich kurzer ist, hab ich eine verschiebung der restlichen spalteneinträge, die darauf folgen!!!
somit wäre es doch sinvoller, wenn ich jedem spalteneintrag eine feste position vorgebe, sprich:

rang (position 1)
name (position 5)
punkte (position 25)
prozent (position 30)

oder nicht!?....

aber ich kenne keinen befehl, wo ich die position klar vorgebe!??


----------



## The_S (6. Apr 2006)

Du musst halt die fehlenden Zeichen mit Leerzeichen auffüllen. Wie gesagt ...


----------



## mermen (6. Apr 2006)

hmmm...ok, aber wie mach ich das am einfachsten...in einer schleife!?...

oder kann ich dem string namen direkt leerzeichen zuweisen!?...


----------



## Leroy42 (6. Apr 2006)

```
int len = name.length();
System.out.print(name);
while (len++ < 15)
  System.out.print(" ");
```


----------



## mermen (6. Apr 2006)

an sowas hab ich ja auch gedacht....aber gibts dafür nichts kürzeres...also, nicht, dass es viel wäre...aber doch ziemlich umständlich....

und es gibt keinen anderen befehl???

gibt es denn keine möglichkeit die position festzulegen.... damit würde ich mir doch das leerzeichen auffüllen sparen!!?


----------



## The_S (6. Apr 2006)

Sry, Leroy42 war schneller bitte löschen.


----------



## Leroy42 (6. Apr 2006)

Nein gibt es nicht!

Da Konsolenbasierte Anwendungsprogramme nicht mehr zeitgemäß
sind, machen sich die Sprachentwickler auch nicht die Mühe, so etwas
zu implementieren. Damals zu TRS-80, C64, Apple II Zeiten gab es 
soetwas noch im eingebauten ROM-Basic. Heutzutage macht es keinen
Sinn mehr.

Edit: Wenn du soetwas öfter brauchst, kannst du dir ja eine Klasse basteln,
die derartiges bereitstellt.


----------



## Leroy42 (6. Apr 2006)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> [edit] da kommt gleich noch was


  :shock: 
Spielst du meinen Vorsänger?


----------



## The_S (6. Apr 2006)

Mir war gerade langweilig


```
public class KonsolenTabelle {
	
	private String[] header = null;
	private String[][] matrix = null;
	
	public KonsolenTabelle(String[] header, String[][] matrix) {
		
		this.header = header;
		this.matrix = matrix;
	}
	
	private int maxBreite(String[] spalte) {
		
		int max = 0;
		for (String str : spalte) {
			if (str.length() > max) {
				max = str.length();
			}
		}
		return max;
	}
	
	private String[] formatLine(String[] line, int[] breiten) {
		
		for (int i = 0; i < breiten.length; i++) {
			while (line[i].length() < breiten[i] + 2) {
				line[i] += " ";
			}
		}
		return line;
	}
	
	public void printTable() {
		
		String[] curSpalte = new String[matrix[0].length + 1];
		int[] breiten  = new int[matrix.length];
		for (int i = 0; i < matrix[0].length; i++) {
			curSpalte[0] = header[i];
			for (int j = 0; j < matrix.length; j++) {
				curSpalte[j + 1] = matrix[j][i];
			}
			breiten[i] = maxBreite(curSpalte);
		}
		header = formatLine(header, breiten);
		for (int i = 0; i < matrix[0].length; i++) {
			matrix[i] = formatLine(matrix[i], breiten);
		}
		for (int i = 0; i < header.length; i++) {
			System.out.print(header[i]);
		}
		System.out.println();
		System.out.println();
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix[i].length; j++) {
				System.out.print(matrix[i][j]);
			}
			System.out.println();
		}
	}
	
	public static void main(String[] args) {
		
		KonsolenTabelle tab = new KonsolenTabelle(new String[] {"Name", "Punkte", "Prozent"}, new String[][] {{"ich", "75", "89"}, {"Papst Johannes Paul II", "70", "85"}, {"du", "90", "95"}});
		tab.printTable();
	}
}
```

Das ganze ist halt ein wenig unschön und "äußerst" Fehleranfällig wenn die Eingaben nicht vorher geprüft wurden. Aber es funktioniert und ich denke darauf kannst du aufbauen

@ Leroy42 bin grad eh weng verwirrt, aber das wird langsam scho Dauerzustand bei mir  :autsch:


----------



## mermen (6. Apr 2006)

@ hobbit
erstmal vielen dank für die mühe!!!

also...so ein ass bin ich leider noch nicht!!!!!

ich hab da mehrere sachen, die ich noch nicht verstehe....dann bleibe ich vielleicht doch lieber bei dem leerzeichen auffüllen....

eigentlich bin ich soweit, dass ich die highscore.txt einlese....
nun wollte ich eine zeile generieren, die mir den aktuellen erspielten spielstand anzeigt....
danach sollten die prozente und die gesamtzahl der gefragten fragen verglichen werden....das muß nix wildes sein....aber ich glaube mir ist dein code zu viel .... 


es sei denn, du erklärst ihn mir schritt für schritt...aber ich glaube ich bräuchte alleine ein paar stunden!!!


----------



## mermen (6. Apr 2006)

```
private int maxBreite(String[] spalte) { 
       
      int max = 0; 
      for (String str : spalte) { 
         if (str.length() > max) { 
            max = str.length(); 
         } 
      } 
      return max;
```


was bedeutet der doppelpunkt in der for - bedingung??


----------



## Leroy42 (6. Apr 2006)

Na dann mal los!

Ist 'ne nette Aufgabenstellung um sich in Java (Imperatives Programmieren allgemein)
einzuarbeiten und Übung zu bekommen.


----------



## mermen (6. Apr 2006)

bedeutet das String [][] matrix das ich ein zweidimensionales array erstelle!??...


----------



## The_S (6. Apr 2006)

mermen hat gesagt.:
			
		

> @ hobbit
> erstmal vielen dank für die mühe!!!



Kein Problem, wie gesagt mir war gerade langweilig  



			
				mermen hat gesagt.:
			
		

> also...so ein ass bin ich leider noch nicht!!!!!



So kompliziert ist es gar nicht, schaut nur so kompliziert aus :lol: 



			
				mermen hat gesagt.:
			
		

> ich hab da mehrere sachen, die ich noch nicht verstehe....dann bleibe ich vielleicht doch lieber bei dem leerzeichen auffüllen....



Das ist die "Mit-Leerzeichen-Auffüll" Methode :bae: 



			
				mermen hat gesagt.:
			
		

> es sei denn, du erklärst ihn mir schritt für schritt...aber ich glaube ich bräuchte alleine ein paar stunden!!!



ok, lässt sich machen. Sag was du nicht ganz verstehst. Bin aber net mehr so lange Online. Ansonsten gehts morgen weiter.



			
				mermen hat gesagt.:
			
		

> was bedeutet der doppelpunkt in der for - bedingung??



Das ist eine neue Schreibweise in Java 5. Du erzeugst praktisch einen String (hier "str") der nur in der Schleife zur Verfügung steht. Mit jedem Durchlauf wird ihm der nächste Wert des Arrays "spalte" zugewiesen. Wenn was unklar ist einfach fragen



			
				mermen hat gesagt.:
			
		

> bedeutet das String [][] matrix das ich ein zweidimensionales array erstelle!??...



Ja, darin speicherst du deine Werte.


----------



## The_S (6. Apr 2006)

So, hab das ganze noch mal ein wenig anschaulicher Gestaltet (musste vorhin weg und war deshalb unter Zeitdruck)

Klasse die die Tabelle erstellt

```
class KonsolenTabelle { 
	
	// gibt die Zeichenzahl des längsten Strings in der Spalte zurück
	
	private int maxBreite(String[] spalte) { 
		 
		int max = 0; 
		for (int i = 0; i < spalte.length; i++) { 
			if (spalte[i].length() > max) { 
				max = spalte[i].length(); 
			} 
		} 
		return max; 
	} 
	
	// formatiert eine Zeile, benötigt die Zeile und die optimalen Breiten
	
	private String[] formatLine(String[] line, int[] breiten) { 
		 
		for (int i = 0; i < breiten.length; i++) { 
			while (line[i].length() < breiten[i] + 2) { 
				line[i] += " "; 
			} 
		} 
		return line; 
	} 
	
	// gibt die benötigte Breite für jede Spalte in einem Array zurück 
	
	private int[] getBreite(String[] head, String[][] matrix) {
		
		String[] curSpalte = new String[matrix[0].length + 1]; 
		int[] breiten  = new int[matrix.length]; 
		for (int i = 0; i < matrix[0].length; i++) { 
			curSpalte[0] = head[i]; 
			for (int j = 0; j < matrix.length; j++) { 
				curSpalte[j + 1] = matrix[j][i]; 
			} 
			breiten[i] = maxBreite(curSpalte); 
		} 
		return breiten;
	}
	
	// gibt die Tabelle aus
	
	private void printTable(String[] head, String[][] matrix) {
		
		for (int i = 0; i < head.length; i++) { 
			System.out.print(head[i]); 
		} 
		System.out.println(); 
		System.out.println(); 
		for (int i = 0; i < matrix.length; i++) { 
			for (int j = 0; j < matrix[i].length; j++) { 
				System.out.print(matrix[i][j]); 
			} 
			System.out.println(); 
		} 
	}
	
	/**
	 * Benötigt den Tabellenkopf und die dazugehörige Matrix, formatiert beides
	 * und gibt anschließend die komplette, formatierte Tabelle in der Standardausgabe
	 * aus
	*/
	
	public void printOut(String[] head, String[][] matrix) { 
		
		if (head.length != matrix.length) {
			System.out.println("Matrix passt nicht zum Head");
		}
		else {
			int[] breiten = getBreite(head, matrix);
			head = formatLine(head, breiten); 
			for (int i = 0; i < matrix[0].length; i++) { 
				matrix[i] = formatLine(matrix[i], breiten); 
			} 
			printTable(head, matrix);
		}
	}
	
	/**
	 * Benötigt den Tabellenkopf und die dazugehörige Matrix
	 * @return
	 * Gibt die formatierte Matrix zurück
	*/
	
	public String[][] getFormattedMatrix(String[] head, String[][] matrix) {
		
		if (head.length != matrix.length) {
			return null;
		}
		else {
			int[] breiten = getBreite(head, matrix);
			for (int i = 0; i < matrix[0].length; i++) { 
				matrix[i] = formatLine(matrix[i], breiten); 
			}
			return matrix;
		}
	}
	
	/**
	 * Benötigt den Tabellenkopf und die dazugehörige Matrix
	 * @return
	 * Gibt den formatierten Tabellenkopf zurück
	*/
	
	public String[] getFormattedHead(String[] head, String[][] matrix) {
		
		if (head.length != matrix.length) {
			return null;
		}
		else {
			int[] breiten = getBreite(head, matrix);
			head = formatLine(head, breiten); 
			return head;
		}
	}
}
```

Klasse die die KonsolenTabelle - Klasse benutzt

```
public class UseKonsolenTabelle {
	
	public static void main(String[] args) {
		
		String[] head = {"Name", "Punkte", "Prozent"};
		String[][] matrix = {{"ich", "75", "89"}, {"Papst Johannes Paul II", "70", "85"}, {"du", "90", "95"}};
		KonsolenTabelle table = new KonsolenTabelle(); 
		table.printOut(head, matrix); 
	}
}
```

Theoretisch könnte man die ganze KonsolenTabelle Klasse auch static machen


----------



## mermen (6. Apr 2006)

sorry, ich mußte dann auch weg....ab wann bist du morgen hier??? ich werde so gegen 9-10 uhr hier sein...vielleicht könnten wir uns dann nochmal über deinen lösungsvorschlag machen, weil ich doch der meinung bin, dass es eine möglichkeit ist, aber nicht das, was ich gern hätte!!

gruß


----------



## The_S (7. Apr 2006)

Ich bin ab jetzt da  :lol: . Was haste dir denn vorgestellt?

BTW: du musst nicht spezifisch mich ansprechen, gibt noch jede menge andere User hier, die dir helfen können (zumal ich ab morgen für ne Woche beim Skifahren bin *freu*  )


----------



## mermen (7. Apr 2006)

hi!

auch wieder da!! ;-)

ja, sorry, dass ich nur dich anspreche...natürlich ist es wünschenswert, dass sich andere user auch mit einschalten, falls sie eine bessere lösung haben!!!

also, deine lösung ist ja nun folgende...dass alles spalten gleich groß sind....nun ja....dass sollen sie aber nicht...weil ich für eine spalte rang wo nur eine zahl drunter steht nicht gerade eine spaltenbreite von 20 zeichen nehmen möchte.....
dein vorschlag gibt das doch so her!!!


----------



## The_S (7. Apr 2006)

Öhm, nein. Jede Spalte ist nur so breit wie unbedingt benötigt wird  ???:L . Wie kommst du darauf das jede Spalte gleich groß ist?


----------



## mermen (7. Apr 2006)

wieso bekomme ich bei dieser berechnung ein falsches ergebnis!????

wenn ich für richtigZaehler = 3 und für insgesamt = 11 


neuprozent = ((int)(((1000*richtigZaehler)/insgesamt)+0.5)/10)

3*100/11 = 27,272727272.....   

möchte es so runden, dass nur eine zahl hinterm komma steht, aber richtig gerundet...also müßte hier doch 27,3 rauskommen....aber irgentwie stimmt etwas mit dem integerwert nicht, den ich zwischenzeitlich erstelle!!!????

weiß da einer weiter??[/b]


----------



## The_S (7. Apr 2006)

mermen hat gesagt.:
			
		

> wieso bekomme ich bei dieser berechnung ein falsches ergebnis!????
> 
> wenn ich für richtigZaehler = 3 und für insgesamt = 11
> 
> ...



Was hat die Frage in diesem Thread zu suchen? Wir machen hier Threads pro Topic und nicht Threads pro User ...

Wenn du mit Kommazahlen rechnest benötigst du double bzw. float Variablen, sonst wird die Zahl nach dem Komma abgeschnitten.

Runden wurde schon 1000 mal besprochen, benutze bitte die Forensuche.


----------



## mermen (7. Apr 2006)

jo, sorry...haste ja recht!

also....ich muß doch als erstes die komplette zeile einlesen....aus meiner highscore.txt...richitg??

was mach ich dann???....ich kann dein code nicht ganz entschlüsseln!!!


----------



## The_S (7. Apr 2006)

Hast du Probleme beim Einlesen deiner Daten oder weißt du nicht genau wie du meine Klasse verwenden musst?


----------



## mermen (7. Apr 2006)

eigentlich wollte ich die highscore einfach nur ausgeben, wobei ich vergleiche, ob der neue eintrag besser ist....wenn das der fall ist, schreibe ich erst den neuen eintrag (in einem string) und dann die restlichen einträge, außer den letzten!

ist das keine gute lösung.....

naja, der neue string ist dann ziemlich lang...aber eigentlich relativ simpel.....


----------



## mermen (7. Apr 2006)

einlesen ist ok....die zeilen schreibe ich dann einzeln in ein array...das klappt schon...

ich verstehe die verwendung nicht....

also, wenn ich eingelesen habe....dann kommt doch die erste methode zum einsatz...richtig!?...


----------



## The_S (7. Apr 2006)

Du benötigst ein Eindimensionales Array vom Typ String, der den Kopf der Tabelle speichert. z. B. Name, Punkte, Prozent, Datum, ... und zwar so:


```
String[] kopf = new String[anzahlDerSpalten];
kopf[0] = "Name";
kopf[1] = "Punkte";
kopf[2] = "Prozent";
kopf[3] = "Datum";
```

das ist dann also mehr oder weniger die "Überschrift" deiner Tabelle. Anschließend benötigst du die Daten in einem Zweidimensionalen Array in der die Daten Zeilenweise gespeichert werden


```
String[][] daten = new String[AnzahlDerZeilen][AnzahlDerSpalten];
daten[0][0] = "Hans"; // 1. Zeile, 1. Spalte (Name)
daten[0][1] = "35"; // 1. Zeile 2. Spalte (Punkte)
daten[0][2] = "63%"; // 1. Zeile 3. Spalte (Prozent)
daten[0][3] = "20.02.2006"; // 1. Zeile 3. Spalte (Datum)
daten[1][0] = "Gabi"; // 2. Zeile, 1. Spalte (Name)
daten[1][1] = "50"; // 2. Zeile 2. Spalte (Punkte)
// usw. usf.
```

Diese beiden Variablen übergibst du dann der Methode printOut(kopf, daten);

Verstanden oder liegt das Problem wo anders?


----------



## mermen (7. Apr 2006)

ach, dann meintest du mit head und matrix den zeilen eintrag und die dazugehörigen spalten....jetzt kapier ichs....

aber was fragst du in der if schleife in printout ab??


----------



## Leroy42 (7. Apr 2006)

```
if (head.length != matrix.length) { 
         System.out.println("Matrix passt nicht zum Head");
```

Hobbit _versucht_ zu prüfen, ob die Anzahl der Spalten der Datenmatrix mit der
Anzahl der Spalten des Spaltenkopfes übereinstimmt.

Was ihm allerdings nicht so ganz gelingt  :bae:


----------



## The_S (7. Apr 2006)

mermen hat gesagt.:
			
		

> ach, dann meintest du mit head und matrix den zeilen eintrag und die dazugehörigen spalten....jetzt kapier ichs....



Dafür kapier ich den Satz nicht und weiß deshalb nicht, was du denkst, was ich mache und kann dir deswegen auch nicht bestätigen bzw. nicht bestätigen dass dieser Satz von dir stimmt :autsch: 



			
				mermen hat gesagt.:
			
		

> aber was fragst du in der if schleife in printout ab??



Ich überprüfe ob die Anzahl der Spalten im Kopf mit der Anzahl der Spalten in den Daten übereinstimmt. Falls dem nicht so ist, wurde mindestens eine falsche Variable übergeben und die Methode würde nicht funktionieren. Man könnte auch an dieser Stelle eine Exception werfen.

[edit]



			
				Leroy42 hat gesagt.:
			
		

> ```
> if (head.length != matrix.length) {
> System.out.println("Matrix passt nicht zum Head");
> ```
> ...



meinste? Ich find das gelingt mir eigentlich ganz gut ...


----------



## Leroy42 (7. Apr 2006)

Menno   

Ich meinte natürlich Tabellenkopf und nicht Spaltenkopf  :autsch: 

Und das Konstrukt nennt sich if-Anweisung und nicht if-Schleife


----------



## Leroy42 (7. Apr 2006)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> meinste? Ich find das gelingt mir eigentlich ganz gut ...



Ich geb dir noch 3 1/2 Minuten um deinen Fehler zu finden.

Ansonsten bekommt die Waschmaschine mit Trockner jemand anders


----------



## The_S (7. Apr 2006)

Schieß los, was mache ich angeblich falsch?  :lol:

[edit] Fehler gefunden  :autsch:


----------



## Leroy42 (7. Apr 2006)

[schild=6 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]Zaunpfahl[/schild]

```
String[][] daten = new String[AnzahlDerZeilen][AnzahlDerSpalten];
```


----------



## The_S (7. Apr 2006)

Wie gesagt gefunden und dazu noch nen ganzen Haufen anderer Fehler  :autsch:   .

Das kommt davon wenn man zum Testen die gleiche Anzahl an Spalten und Zeilen verwendet ... sry besser es gleich aus


----------



## Leroy42 (7. Apr 2006)

@ mermen (solange Hobbit seinen Frühjahrsputz macht)


```
String[][] daten = new String[AnzahlDerZeilen][AnzahlDerSpalten];
```

Mit daten.length bekommt man immer die Anzahl der Elemente des _äußersten_
(am weitesten links stehenden Indizes). In diesem Fall also die Anzahl der Zeilen und
nicht die Anzahl der Spalten der Datentabelle. Und diese muß natürlich _nicht_ mit
der Länge des Tabellenkopf-Arrays (also der Anzahl der Spalten) übereinstimmen.

Hoffe, ich habe mich einigermaßen verständlich ausgedrückt.  :autsch:


----------



## The_S (7. Apr 2006)

War gestern ein wenig überarbeitet   


```
class KonsolenTabelle { 
	
	// gibt die Zeichenzahl des längsten Strings in der Spalte zurück 
	 
	private int maxBreite(String[] spalte) { 
		 
		int max = 0; 
		for (int i = 0; i < spalte.length; i++) { 
			if (spalte[i].length() > max) { 
				max = spalte[i].length(); 
			} 
		} 
		return max; 
	} 
	 
	// formatiert eine Zeile, benötigt die Zeile und die optimalen Breiten 
	 
	private String[] formatLine(String[] line, int[] breiten) { 
		 
		for (int i = 0; i < breiten.length; i++) { 
			while (line[i].length() < breiten[i] + 2) { 
				line[i] += " "; 
			} 
		} 
		return line; 
	} 
	 
	// gibt die benötigte Breite für jede Spalte in einem Array zurück 
	 
	private int[] getBreite(String[] head, String[][] matrix) { 
		 
		String[] curSpalte = new String[matrix.length + 1]; 
		int[] breiten  = new int[matrix[0].length]; 
		for (int i = 0; i < matrix[0].length; i++) { 
			curSpalte[0] = head[i]; 
			for (int j = 0; j < matrix.length; j++) { 
				curSpalte[j + 1] = matrix[j][i]; 
			} 
			breiten[i] = maxBreite(curSpalte); 
		} 
		return breiten; 
	} 
	 
	// gibt die Tabelle aus 
	 
	private void printTable(String[] head, String[][] matrix) { 
		 
		for (int i = 0; i < head.length; i++) { 
			System.out.print(head[i]); 
		} 
		System.out.println(); 
		System.out.println(); 
		for (int i = 0; i < matrix.length; i++) { 
			for (int j = 0; j < matrix[i].length; j++) { 
				System.out.print(matrix[i][j]); 
			} 
			System.out.println(); 
		} 
	} 
	 
	/** 
	 * Benötigt den Tabellenkopf und die dazugehörige Matrix, formatiert beides 
	 * und gibt anschließend die komplette, formatierte Tabelle in der Standardausgabe 
	 * aus 
	*/ 
	 
	public void printOut(String[] head, String[][] matrix) { 
		 
		if (head.length != matrix[0].length) { 
			System.out.println("Matrix passt nicht zum Head"); 
		} 
		else { 
			int[] breiten = getBreite(head, matrix); 
			head = formatLine(head, breiten); 
			for (int i = 0; i < matrix.length; i++) { 
				matrix[i] = formatLine(matrix[i], breiten); 
			} 
			printTable(head, matrix); 
		} 
	} 
	 
	/** 
	 * Benötigt den Tabellenkopf und die dazugehörige Matrix 
	 * @return 
	 * Gibt die formatierte Matrix zurück 
	*/ 
	 
	public String[][] getFormattedMatrix(String[] head, String[][] matrix) { 
		 
		if (head.length != matrix[0].length) { 
			return null; 
		} 
		else { 
			int[] breiten = getBreite(head, matrix); 
			for (int i = 0; i < matrix.length; i++) { 
				matrix[i] = formatLine(matrix[i], breiten); 
			} 
			return matrix; 
		} 
	} 
	 	
	/** 
	 * Benötigt den Tabellenkopf und die dazugehörige Matrix 
	 * @return 
	 * Gibt den formatierten Tabellenkopf zurück 
	*/ 
	 
	public String[] getFormattedHead(String[] head, String[][] matrix) { 
		 
		if (head.length != matrix[0].length) { 
			return null; 
		} 
		else { 
			int[] breiten = getBreite(head, matrix); 
			head = formatLine(head, breiten); 
			return head; 
		} 
	} 
}
```


```
public class UseKonsolenTabelle { 
	 
	public static void main(String[] args) { 
		 
		String[] head = {"Name", "Punkte", "Prozent"}; 
		String[][] matrix = {{"Horst", "75", "89"}, {"Julia", "70", "85"}, {"Nadine", "90", "95"}, {"Paul", "50", "70"}}; 
		KonsolenTabelle table = new KonsolenTabelle(); 
		table.printOut(head, matrix); 
	} 
}
```

müsste jetzt passen


----------



## mermen (7. Apr 2006)

naja...ich meinte die variable matrix....das wären dann also daten?!...oder??


----------



## The_S (7. Apr 2006)

mermen hat gesagt.:
			
		

> naja...ich meinte die variable matrix....das wären dann also daten?!...oder??



ja


----------



## mermen (7. Apr 2006)

jungs...langsam....bitte ....also wenn ich das gerade verstanden habe, war die erstellung des zweidimensionalen array falsch...richtig???


----------



## The_S (7. Apr 2006)

Nein, ich hatte nen Fehler im Code   . Du musst einfach den Code den ich gerade eben gepostet habe übernehmen. Ansonsten ändert sich nichts.


----------



## mermen (7. Apr 2006)

nun muß ich mal kurz nachschauen wie ich meine textdatei zeilenweise auslese und die zeile zerlege!!


----------



## The_S (7. Apr 2006)

Zeilenweise auslesen


```
BufferedReader buffy = new BufferedReader(new FileReader("deine.txt"));
String eineZeile = null;
while ((eineZeile = buffy.readLine()) != null) {
    // mach was mit der Zeile
}
```

String an bestimmter Stelle teilen (z. B. ein Leerzeichen)


```
String[] amLeerzeichenGesplitet = zeile.split(" ");
```


----------



## mermen (7. Apr 2006)

ja, an split hab ich auch gedacht...aber wenn ich nun....

rang;name;richtung;....habe, soll er doch nicht nur einmal teilen....sondern die ganze zeile immer fortlaufend...und jeweils die "abschnitte" in variablen hinterlegen.....

wie du halt meintest mit der zuweisung des head!!


----------



## The_S (7. Apr 2006)

Wie schaut denn deine Datei aus?


----------



## mermen (7. Apr 2006)

also nun hab ich sie geändert :

rang;name;richtung;insgesamt;richtig;falsch;prozent
1;hans;deutsch->englisch;20;15;5;75,0
2;kurt;englisch->deutsch;40;20;20;50,0
.
.
.
.
usw...


----------



## Leroy42 (7. Apr 2006)

mermen hat gesagt.:
			
		

> sondern die ganze zeile immer fortlaufend...



Genau das macht _split_ ja. Du kannst dann in einer Schleife einfach

daten[zeilennummer] = zeile.split(';') schreiben.

Das einzige Problem ist noch, _vorher_ die Anzahl der Zeilen der Datei
zu bestimmen umd _daten_ genügend groß zu machen.

Du kannst die von split erzeugten Stringarrays erst mal in einen Vector(ArrayList)
schreiben, und am Ende daraus einen Array erzeugen. Falls du dich mit Collections
allerdings überhaupt noch nicht auskennst, empfehle ich, bei deinen kleinen Datenmengen,
einfach die Datei zweimal einzulesen. Beim ersten Mal bestimmst du dann nur die
Anzahl der Zeilen, sodaß du _daten_ richtig dimensionieren kannst.


```
String[][] daten = new String[anzahlZeilen][];
```

Beim zweiten Durchlaufs speicherst du dann die Daten wie Hobbit und ich beschrieben haben.


----------



## The_S (7. Apr 2006)

OK, Leroy42 hats dir schon beschrieben (@Leroy42, man sind wir ein Team ...  :bae:  ). Das einzige was mir noch auffällt ist eine Kleinigekeit an deinen Daten.

Du hast 7 Spalten im Kopf, aber 8 in den Daten (die letzte 0 ist zuviel). Wenn das absicht ist musste das natürlich dann später mitberücksichtigen. Ansonsten ausbessern .


----------



## mermen (7. Apr 2006)

da ich immer nur 10 zeilen der highscore anzeigen möchte, kann ich doch eine feste größe vorgeben....oder?


----------



## mermen (7. Apr 2006)

die letzte null gehört doch zu prozent...also 50,0 trennzeichen ist doch ein ";"  ??


----------



## The_S (7. Apr 2006)

ja, dann brauchst du allerdings auch eine andere Schleife die nach 10 Zeilen (oder besser 11, da du den Kopf ja auch noch lesen musst) oder wenn das Ende der Datei erreicht ist aufhört zu lesen.

[edit] Achja richtig. Komma und Semikolon sehen sich so verdammt ähnlich


----------



## Leroy42 (7. Apr 2006)

mermen hat gesagt.:
			
		

> kann ich doch eine feste größe vorgeben....oder?



Eigentlich schon, aber das ist  :bae: 
(Außerdem sind ja nicht vom Spiel-Urknall an gleich 10 Highscores vorhanden)

Sei doch flexibel, und speichere die aktuelle Anzahl der Zeilen gleich mit in deiner
Datei. Dann ersparst du dir sowohl Collection-Gerödel als auch doppeltes Datei einlesen:

rang;name;richtung;insgesamt;richtig;falsch;prozent 
10
1;hans;deutsch->englisch;20;15;5;75,0 
2;kurt;englisch->deutsch;40;20;20;50,0 
. 
. 
. 
.
Edit: Und wieviele du dann anzeigst, bleibt deinem Programm überlassen. Evtl. auch dem User deines Programms.


----------



## Leroy42 (7. Apr 2006)

Sorry, hab' noch ein paar Punkte vergessen, sind ja 10 highscores nach meiner Tabelle

```
....
```
Die Zeilenumbrüche poste ich mal nicht mit: Man muß ja nicht, ... nicht unbedingt


----------



## mermen (7. Apr 2006)

naja...ich werde die datei einfach mit 10 zeilen befüllen....also, muß nicht unbedingt flexibel sein...

nun hab ich ein problem mir den eingelesenen zeilen...

hatte das array in die klasse geschrieben :

String [] zeile = new String [11];

dann lese ich in einer methode die zeilen einzeln aus und speicher sie im array...nun sagt er mir, wenn ich die zeile in einer anderen methode aufrufen möchte...

kopf[spaltenanzahl] = zeile[zeilen].split(";");

dass "Erstellen eines statischen (static) Verweises für das nicht-statische Feld zeile nicht möglich"....

wo liegt mein fehler??


----------



## The_S (7. Apr 2006)

Das du irgendwo static verwendet hast wo du es nicht sollst. Ohne Code ist es schwer zu sagen wo genau der Fehler liegt.


----------



## mermen (7. Apr 2006)

wenn ich die zeilen in das "klassenarray: zeile" einlese....in einer methode brauche ich einen rückgabewert in meiner methode???

ich habe da puplic void einlesenHighscore....muß ich dass array zurückgeben??? das geht doch gar nicht....????

static hab ich in der class "highscore" gar nicht verwendet!!


----------



## Leroy42 (7. Apr 2006)

Sicher kannst du ein Array zurückgeben (ist schließlich nur eine Referenz).

Du kannst dein Kopf-Array und das Datenarray allerdings auch als Instanzvariable
deklarieren, sodaß _einlesenHighscore_ dann direkt drauf zugreifen kann.

Trotzdem, wie Hobbit schon meinte, poste mal den Code von einlesenHighscore


----------



## mermen (7. Apr 2006)

der anfang:


```
import java.io.*;

public class Highscore 
{
	
	String [] zeile = new String [11];
	String name = "";
	float neuprozent;
```

dann:


```
public void einlesenHighscore ()
	{ 
	try 
	    { 
	    	String leseZeile = "";
	    	int zeilenzaehler = 0;	    
	    	BufferedReader Datei = new BufferedReader(new FileReader("Highscore.txt"));
	    	
	    	while ((leseZeile = Datei.readLine()) != null)  
			{ 
	            
	            	zeile [zeilenzaehler]= leseZeile;
	          
	            zeilenzaehler = zeilenzaehler + 1;
			
			} 
	       	Datei.close(); 
	       
	    }    
	     
	    catch (FileNotFoundException error)
	    {
	    	 System.out.println(" Datei nicht gefunden! Bitte stellen sie sicher, dass die Textdatei ´Highscore´im richtigen Ordner und vorhanden ist!");
	    } 
	    catch (IOException error) 
	     
	    { 
	    	 System.out.println(" Fehler beim Lesen der Datei!!"); 
	    }
	}
```

und nun bin ich hier....


```
public void stringZerlegung()
	{
		int zeilenzaehler = 0;
		
		while (zeilenzaehler<= 10)
		{
			if (zeilenzaehler == 0)
			{
				String[] kopf = new String[7]; 
				
				int zeilenanzahl = 0;
				while (zeilenanzahl <= 10)
				{
					String zeilen =zeile[zeilenanzahl];
					int spaltenanzahl = 0;
					while (spaltenanzahl <= 7)
					{
						kopf[spaltenanzahl] = zeilen.split(";");
						spaltenanzahl++;
			
					}
					zeilenanzahl++;
				}
			}
		
		}
		
	}
```


und...nun folgende fehlermeldung: "Typabweichung: Konvertierung von String[] auf String nicht möglich"

edit: in dieser zeile: kopf[spaltenanzahl] = zeilen.split(";");


----------



## The_S (7. Apr 2006)

Du splitest in einen String, musst aber in ein String-Array spliten.

kopf = zeilen.split(";");

btw: bin jetzt weg (weiß net ob ich überhaupt nochmal vor der Woche Urlaub morgen komm), leroy42, übernehmen sie


----------



## Leroy42 (7. Apr 2006)

Wie wir dir bereits mehrfach gesagt haben: split liefert bereits einen Stringarray.

Du kannst dir das gesamte Schleifengerödel also sparen und einfach schreiben

```
String[] kopf = zeilen.split(";");
```

Außerdem definierst du kopf lokal in der Methode und gibst ihn nicht zurück ==> Inhalt geht verloren.

Ich schreibe gleich mal ein Skelett.


----------



## Leroy42 (7. Apr 2006)

Hier mal das Grundgerüste *ohne* vollständige Fehlerbehandlung

```
public class Highscore {
	static final int SCORES = 10;

	String[] kopf;
	String[][] daten = new String[SCORES][];

	public boolean liesHighscore() {
		try {
			BufferedReader highscore = new BufferedReader(new FileReader("Highscore.txt"));
			kopf = highscore.readLine().split(';');
			for (int i=0; i<SCORES; ++i) {
				String zeile = highscore.readLine();
				if (zeile == null) {
					System.err.println("Datei zu klein");
					return false;
				} else
					daten[i] = zeile.split(';');
			}
		}
		return true;
	}
}
```


----------



## mermen (7. Apr 2006)

warum gebe ich einen boolean wert zurück, hat das einen hintergrund...wofür bräuchte ich den???


----------



## Leroy42 (7. Apr 2006)

Du mußt es nicht unbedingt.

Aber da du in dieser Methode IO-Operationen machst, die mißlingen könnten (Scanner fällt
auf USB-Memory-Stick auf der die Highscore-Datei gespeichert ist und bricht ab)
mußt du entsprechend reagieren. Und da deine Methode keine Exception wirft, weiß
die aufrufende Methode ja gar nicht, ob und wie die Datei eingelesen wurde. Sie würde
bein einem IO-Fehler einfach mit einem evtl. halb-kaputten Daten weitermachen.

Der boolean soll dem Aufrufer zeigen, ob das Einlesen geklappt hat.


----------



## norman (7. Apr 2006)

na in leroy42s beispiel liefert die methode true zurück, wenn das lesen der highscrore geklappt hat. im fehlerfalle false..

die daten sind ja in den instanzvariablen (klassenvariablen) kopf und daten gespeichert..

[edit]..ein paar sekunden..hm
btw: deine signatur is so geil, leroy42  :lol:  :lol:


----------



## mermen (7. Apr 2006)

aber das selbe kann ich ja auch bewirken, indem ich eine catch-anweisung einfüge, die im fehlerfall dann anspringt!?...also füge ich eine catch-anweisung ein und spare mir das boolean....

(denn wie oft fällt mein scanner auf meinen usb-stick wo ich dann auch noch gleichzeitig die highscore einlese!!?? ;-)  )


----------



## Leroy42 (7. Apr 2006)

norman hat gesagt.:
			
		

> btw: deine signatur is so geil, leroy42  :lol:  :lol:


Finde ich auch   

Darum habe ich _fantasygirl_, eine Teilnehmerin eines anderen Forums bei
der ich sie gefunden habe, auch gleich gefragt ob ich *sie* in diesem Forum benutzen
darf   

Edit: Mit dem letzten _sie_ meinte ich natürlich die Signatur  :shock:


----------



## norman (7. Apr 2006)

Leroy42 hat gesagt.:
			
		

> Edit: Mit dem letzten _sie_ meinte ich natürlich die Signatur  :shock:


gut, dass du es dazu sagst  :wink:


----------



## Leroy42 (7. Apr 2006)

mermen hat gesagt.:
			
		

> aber das selbe kann ich ja auch bewirken, indem ich eine catch-anweisung einfüge, die im fehlerfall dann anspringt!?...also füge ich eine catch-anweisung ein und spare mir das boolean....



Das ist richtig. Aber was machst du dann in dem catch-Block? Da der Aufrufer der Methode ja nicht
mitbekommt, daß etwas schiefging und einfach weitermachen würde, bleibt dir ja nur übrig, nach 
Ausgabe einer Fehlermeldung, mit System.exit(_irgendwas_) das Programm zu beenden.

Naja, vielleicht initialisierst du kopf und daten mit leeren Werten und interpretierst den Einlesefehler
als noch nicht vorhande Highscore-Tabelle; dann könnte das Programm ja auch weiterlaufen und
müßte nicht beendet werden.


----------



## norman (7. Apr 2006)

mermen hat gesagt.:
			
		

> aber das selbe kann ich ja auch bewirken, indem ich eine catch-anweisung einfüge, die im fehlerfall dann anspringt!?...also füge ich eine catch-anweisung ein und spare mir das boolean....
> 
> (denn wie oft fällt mein scanner auf meinen usb-stick wo ich dann auch noch gleichzeitig die highscore einlese!!?? ;-)  )


wenn du den fehler in der methode liesHighscore() mit einem catch auffängst, ist das ja erstmal nicht schlecht. aber davon kriegt die aufrufende methode (zb die main()) nicht zwangsläufig etwas mit.

du rufst beispielsweise irgendwo auf:

anweisung1();
liesHighscore();
anweisung2();

..anweisung2 brauch evtl die daten, die in *kopf* und *daten* von liesHighscore() reingeschrieben wurden. wenn das aber nicht geklappt hat, siehts schlecht aus für anweisung2
=> darum:

```
anweisung1();
boolean geklappt = liesHighscore();
if (geklappt) {
   anweisung2();
} else {
   // evtl. nochmal liesHighscore() versuchen oder sowas..
}
```


----------



## mermen (7. Apr 2006)

ich habe gerade folgende fehlermeldung beim split:

Die Methode split(String, int) im Typ String ist für die Argumente nicht anwendbar (char)


----------



## Leroy42 (7. Apr 2006)

norman hat gesagt.:
			
		

> ```
> // evtl. nochmal liesHighscore() versuchen
> ```



Der war gut!   
[schild=8 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]Ich gebe nicht auf! Verdammich, es muß doch mal klappen![/schild]


----------



## norman (7. Apr 2006)

[edit] das ist bockmist, einfach überspringen.. [/edit]

split(deinString, ';');
nicht: split(deinString, ";");
- glaube ich


----------



## Leroy42 (7. Apr 2006)

Du benutzt auch die falsche Methode:

String[] split(String regExpr)

Ich sehe gerade, daß du einen regulären Ausdruck, keinen char, übergeben mußt. 
Daher doppelte Anführungszeichen um das Semikolon
kopf = zeile.split(";")


----------



## mermen (7. Apr 2006)

norman hat gesagt.:
			
		

> split(deinString, ';');
> nicht: split(deinString, ";");
> - glaube ich



ist schon geändert....hatte ich vorhin nur mal probiert...aber egal...stet nun so! 

kopf = highscore.readLine().split(';');


----------



## mermen (7. Apr 2006)

ok...fehler beseitigt!!!! ;-)

waren die ";" statt ';'


----------



## mermen (7. Apr 2006)

also...ich aber nun echt überfragt, wie ich nun weitermache....nun kann ich doch die klasse von hobbit verwenden...oder???


----------



## mermen (7. Apr 2006)

bist du noch da leroy42??


----------



## Leroy42 (7. Apr 2006)

nööh


----------



## mermen (7. Apr 2006)

kannst du mir sagen, wann die methoden 

getFormattedHead(String[] head, String[][] matrix)
getFormattedmatrix(String[] head, String[][] matrix)
 verwendet werden???

rufe ich die separat auf??


----------



## Leroy42 (7. Apr 2006)

Prinzipiell sollte das jetzt mit Hobbits Klassen funktionieren.

An manchen Stellen kannst du dir die Übergabe deiner Daten (head, data) ersparen, da
diese jetzt ja als Instanzvariablen vorliegen und dadurch von jeder Methode direkt
benutzt werden können.


----------



## The_S (7. Apr 2006)

mermen hat gesagt.:
			
		

> kannst du mir sagen, wann die methoden
> 
> getFormattedHead(String[] head, String[][] matrix)
> getFormattedmatrix(String[] head, String[][] matrix)
> ...



Die verwendest du wenn du noch was anderes mit der Tabelle machen möchtest, sie dafür aber zur Ausgabe bereit formatiert sein muss (kA für was du die gebrauchen kannst, ich habs halt ma eingebaut ...  )


----------



## mermen (8. Apr 2006)

ok....dann werd ich sie wohl einfach weglassen!!
es sei denn jemand nennt mir einen guten grund sie doch noch zu benutzen!??...


----------



## Leroy42 (8. Apr 2006)

Sie sind zumindest mit Vorsicht zu genießen.
Die Namen _getFormatted..._ suggerieren, daß es Methoden seien, die
_nur_ etwas zurückliefern.

In Wahrheit verändert aber getFormattedMatrix auch das übergebene Array.   

Deshalb sollte es besser heißen _formatMatrix_. Die jetzt formatierte Matrix
kann natürlich immer noch zurückgegeben werden.


----------



## mermen (8. Apr 2006)

irgentwie verstehe ich nicht was die methode "getBreite(...)" auf seite 3 dieses threads macht...kann mir das einer erklären???
schritt für schritt....

ich weiß zwar was ich rauskriege...aber ich kann den ablauf irgentwie nicht nachvollziehen!??...


----------



## mermen (8. Apr 2006)

hier nochmal der code den ich nicht verstehe....




```
class KonsolenTabelle { 
	
		 
	// gibt die benötigte Breite für jede Spalte in einem Array zurück 
	 
	private int[] getBreite(String[] head, String[][] matrix) { 
		 
		String[] curSpalte = new String[matrix.length + 1]; 
		int[] breiten  = new int[matrix[0].length]; 
		for (int i = 0; i < matrix[0].length; i++) { 
			curSpalte[0] = head[i]; 
			for (int j = 0; j < matrix.length; j++) { 
				curSpalte[j + 1] = matrix[j][i]; 
			} 
			breiten[i] = maxBreite(curSpalte); 
		} 
		return breiten; 
	}
```


----------



## Leroy42 (8. Apr 2006)

```
// gibt die benötigte Breite für jede Spalte in einem Array zurück 
    
   private int[] getBreite(String[] head, String[][] matrix) { 

      // curSpalte betrachtet jeweils eine Spalte der Matrix
      String[] curSpalte = new String[matrix.length + 1]; 

      // breiten beinhaltet für jede Spalte die maximale Anzahl der Zeichen in dieser Spalte
      int[] breiten  = new int[matrix[0].length]; 

      // i durchläuft die Spalten
      for (int i = 0; i < matrix[0].length; i++) { 

         // der Tabellenkopf ist auch Teil der Spalte
         curSpalte[0] = head[i]; 

         // j durchläuft jede Zeile der Matrix der i-ten Spalte
         for (int j = 0; j < matrix.length; j++) { 

            // Der Inhalt der Zelle wird in das Zielarray kopiert
            curSpalte[j + 1] = matrix[j][i]; 
         } 

         // Die Methode maxBreite bestimmt jetzt die maximale Zeichenanzahl von curSpalte
         // diese wird in das breiten-Array gespeichert.
         breiten[i] = maxBreite(curSpalte); 
      } 

      // Rückgabe aller Maximalspaltenbreiten
      return breiten; 
   }
```

Das funktioniert zwar so, allerdings werden die Texte selbst unnötigerweise
kopiert. Man könnte das Kopieren vermeiden, indem man die Bestimmung
des jeweiligen Maximums in diese Methode integriert. Bei diesen kleinen
Datenmengen ist das aber vollkommen schnurz; eben Geschmackssache.


----------



## mermen (8. Apr 2006)

also du meinst, dass ich die spaltengröße vorgeben kann....so dass nicht jede spalte auf ihre länge überprüft wird....hab ich das richtig verstanden!??....

dann bräuchte ich doch die gesamte mehtode nicht....oder???


----------



## mermen (9. Apr 2006)

also, so wie es zur zeit steht, ist das ok für mich....ich werde das wohl so lassen, da ich eh keine aufwendigen daten bearbeiten muß, sondern nur diese 10 highscoreeinträge!!!

also, das mit der ausgabe klappt nun, aber ich muß natürlich meinen aktuell, erspielten eintrag überprüfen, ob er nun besser ist als die anderen und ihn dann auch in der highscore speichern...

hat da jemand einen guten ansatz??...
ich krieg das ja nun hin, dass ich die prozente miteinander vergleiche...aber ich müßte doch die zeilen wieder erneut einlesen (aus der datei) und (wenn nötig) die reihenfolge verändern und wieder abspeichern.....


----------



## The_S (16. Apr 2006)

Sortier nach der Prozentzahl und schmeiß den letzten Eintrag raus.

@ Leroy42 immer diese Code-Fuchserei ... das war doch nur schnell hingeklatscht, lasst mich halt in ruhe von wegen Methoden-Namen und Performance ...  :wink:


----------

