ASCII-Bild einlesen

pisco

Bekanntes Mitglied
Hey Leute,

wenn ich dieses Bild einlese und kompiliere

Java:
read 27
============,.V+.;============
===========;.X##..;===========
===========..####..===========
==========,.##M###.:==========
=========;.R##WW##=.;=========
=========..##MWMW##,.=========
========:.I##WWMWW#W.,========
=======;.:##WWWWWW##I.;=======
=======:.W########M##..=======
=======.:############V.;======
=======.####...,.,M###,.======
======,.###:..+++;,B..#.;=====
=====;.#;.#i+YXVVY:#V.#..:====
====:..#..##.RYYIt##...#=.,===
==;..+#;...#######W....##W..:=
:..t###......iVV=....,.+#iM#..
.B#i,#..,,..........,,..#,..#I
V#...#..,,,,,.,,,,:,,,..R#..V#
;#+.i#..,,,,,,,,,.,,,,,.iX.X#,
.i#=MV..,,,,.,,,,,,.,,,..###..
,.t##..,,,,,,,,,,,,,,:,..V##.;
..M#M..,,,,.,.,,,,,,,:,,.=##..
i###M..,...........,,:,,..###.
.####........=II;.....,,.;##R.
,...#....X####MW###B.....Wi..:
==;,##,###;........##i...#;,==

mit dem source:

Java:
import java.util.*;//alles importieren was in dem util-Verzeichnis steht
public class AsciiShop {
	
	
	public static void main(String[] args) {// der Hauptteil des Porgramms
		
		Scanner sc = new Scanner(System.in);
		
		String bild = "";
		String zeile= "";
		int zeilenanzahl = 0;
		int counter = 0;
		int breite = 0;
		String schluessel = "";
		
		//1.Anforderungen überprüfen & einlesen falls es passt
		if(sc.next().equals("read") && sc.hasNextInt()) {
			zeilenanzahl = sc.nextInt();
			counter = zeilenanzahl;
			sc.nextLine();
			
			
			//2. Bild einlesen und fertig machen zum decodieren
			while(sc.hasNextLine() && counter>0) {
				zeile = sc.nextLine();
				
				if (breite == 0)//die breite wird definiert 
				{
					
					breite = zeile.length();
					//System.out.println(breite);
				} /*else {//hier ist die breite != zeile.length also:
				System.out.println("INPUT MISMATCH2");
				// WENN ICH DAS LASSE DANN WIRD INPUT MISMATCH SEHR OFT AUSGEGEBEN, WEIL NACH DEM ERSTEN DURCHLAUF DIE BREITE != 0 ist	
				}*/
				
				counter--;//counter zurücksetzten-> schleifen ausstieg
				bild += zeile;//der String wird zum bild "hinzugefügt"
				
			}
		}
		else {
			System.out.println("INPUT MISMATCH");
		}
		
		//3. decodieren und die Macht des bild-Strings bzw. einige kleine Feinheiten die noch am bild zu machen sind
		if(counter != 0){
			System.out.println("INPUT MISMATCH");
		}//wird ausgegeben falls der counter ungleich 0 is
		
		//decode einlesen bzw. vorher überprüfe ob weiteres Zeichen einzulesen ist
		if(sc.hasNext()) {	
			zeile = sc.next();
			if(zeile.equals("decode")) {
				if(sc.hasNext()) {	//Schlüsselkontrolle + übergabe von neuem Bild
					schluessel = sc.next();
					if(checkKey(schluessel, bild.length())==true) {
						bild = decode(bild, schluessel);
					} else {
						System.out.println("INVALID KEY");
					}
				} else {
					System.out.println("INVALID KEY");
					
				}
			} /*else {
			System.out.println("INPUT MISMATCH4");
			}*/
		}
		
		//4.Ausfabe des entschlüsselten Bildes und FERTIG°°
		for(int i = 0; i<zeilenanzahl; i++)
		{
			
			System.out.println(bild.substring(i*breite, (i*breite)+breite));//<= here spielt sich die Action ab nach den ganzen Berechnungen^^
		}
		System.out.println(breite+ " " + zeilenanzahl);
		
	}	
	//3.1 - Methoden...ein kleiner abstecher was wir in 3 brauchen
	static boolean checkKey(String schluessel, int bildlaenge)//static: Das Schlüsselwort static wird immer dann verwendet, wenn die Funktionalität, die eine Methode bereitstellt, nicht für ein konkretes Objekt gilt, sondern unabhängig von Objekten bereit gestellt werden soll.
	{
		if((bildlaenge % schluessel.length()) != 0){
			System.out.println("INVALID KEY");
		} else {
			
			//ob jede Ziffer einzeln vorkommt (s.u)
			int keylength = schluessel.length();
			for(int i = 0; i<keylength; i++) {
				if((schluessel.indexOf(""+i)==-1) || (schluessel.lastIndexOf(""+i) != schluessel.indexOf(""+i))) {
					return false;
				}
			}
		}
		
		return true;
	}
	//die Deocodierung des bildes mit speichern der Zeichen in temp2 und übergabe von decoded
	static String decode(String bild, String schluessel)
	{
		String decoded = "";
		int keylength = schluessel.length();
		for(int i = 0; i < (bild.length()/keylength); i++) {
			String temp = bild.substring(i*keylength, (i*keylength)+keylength);
			char []temp2 = new char[temp.length()];
			
			for(int j = 0; j < keylength; j++) {
				temp2[j] = temp.charAt(Integer.valueOf(""+schluessel.charAt(j)));
			}
			decoded += new String(temp2);
		}
		return decoded;
	}
	
	//END
	
}

krieg ich folgende Fehlermeldung:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 810
at java.lang.String.substring(String.java:1946)
at AsciiShop.main(AsciiShop.java:86)

was heißt das?

gruss und dank euch für all eure Verbesserungsvorschläge(auch codetechnisch^^)

PS.: ich bedank mich schonmal für eure Hilfe im Vorraus
 
Zuletzt bearbeitet von einem Moderator:
in deinem code in zeile 86 nutzt die die Funktion substring mit dem Index 810. Dein String ist aber kleiner als die 810 zeichen, ergo outofbounds.

somit stimmt deine berechnung nicht gnanz
 
Stimmen die Zeilennummern bei dir mit den hier geposteten überein? Zeile 86 ist nämlich leer.
In Zeile 75 und 104 wird String.substring() verwendet, wie in der Fehlermeldung beschrieben, da wird also wohl auf einen Index 810 zugegriffen, den es in dem String nicht gibt. Weiß aber nicht, welche von beiden Zeilen es ist, da wie gesagt die Zeilenangabe nicht übereinstimmt.
 
SO noch mal den Code überarbeitet

Java:
import java.util.*;//alles importieren was in dem util-Verzeichnis steht
public class AsciiShop {
	
	
	public static void main(String[] args) {// der Hauptteil des Porgramms
		
		Scanner sc = new Scanner(System.in);
		
		String bild = "";
		String zeile= "";
		int zeilenanzahl = 0;
		int counter = 0;
		int breite = 0;
		String schluessel = "";
		
		//1.Anforderungen überprüfen & einlesen falls es passt
		if(sc.next().equals("read") && sc.hasNextInt()) {
			zeilenanzahl = sc.nextInt();
			counter = zeilenanzahl;
			sc.nextLine();
			
			//2. Bild einlesen und fertig machen zum decodieren
			while(sc.hasNextLine() && counter>0) {
				zeile = sc.nextLine();
				
				if (breite == 0)//die breite wird definiert 
				{
					
					breite = zeile.length();
					//System.out.println(breite);
				} /*else {//hier ist die breite != zeile.length also:
				System.out.println("INPUT MISMATCH2");
				// WENN ICH DAS LASSE DANN WIRD INPUT MISMATCH SEHR OFT AUSGEGEBEN, WEIL NACH DEM ERSTEN DURCHLAUF DIE BREITE != 0 ist	
				}*/
				
				counter--;//counter zurücksetzten-> schleifen ausstieg
				bild += zeile;//der String wird zum bild "hinzugefügt"
				
			}
			
			if(counter != 0) {
				System.out.println("INPUT MISMATCH");
				return;
			} // WARUM STEIGT ER HIER NED AUSSDEM PROGRAM AUS?
			
		}	
		//Fehlerabfrage bei zu wenig / zu viel Zeileneingaben
		
		else {
			System.out.println("INPUT MISMATCH");
			return;
		}
		
		//3. decodieren und die Macht des bild-Strings bzw. einige kleine Feinheiten die noch am bild zu machen sind
		if(counter != 0){
			System.out.println("INPUT MISMATCH");
			return;
		}//wird ausgegeben falls der counter ungleich 0 is
		
		//decode einlesen bzw. vorher überprüfe ob weiteres Zeichen einzulesen ist
		if(sc.hasNext()) {	
			zeile = sc.next();
			if(zeile.equals("decode")) {
				if(sc.hasNext()) {	//Schlüsselkontrolle + übergabe von neuem Bild
					schluessel = sc.next();
					if(checkKey(schluessel, bild.length())==true) {
						bild = decode(bild, schluessel);
					} else {
						System.out.println("INVALID KEY");
					}
				} else {
					System.out.println("INVALID KEY");
					
				}
			} /*else {
			System.out.println("INPUT MISMATCH4");
			}*/
		}
		
		//4.Ausfabe des entschlüsselten Bildes und FERTIG°°
		for(int i = 0; i<zeilenanzahl; i++)
		{
			
			System.out.println(bild.substring(i*breite, (i*breite)+breite));//<= here spielt sich die Action ab nach den ganzen Berechnungen^^
		}
		System.out.println(breite+ " " + zeilenanzahl);
		
	}	
	//3.1 - Methoden...ein kleiner abstecher was wir in 3 brauchen
	static boolean checkKey(String schluessel, int bildlaenge)//static: Das Schlüsselwort static wird immer dann verwendet, wenn die Funktionalität, die eine Methode bereitstellt, nicht für ein konkretes Objekt gilt, sondern unabhängig von Objekten bereit gestellt werden soll.
	{
		if((bildlaenge % schluessel.length()) != 0){
			System.out.println("INVALID KEY");
			
		} else {
			
			//ob jede Ziffer einzeln vorkommt (s.u)
			int keylength = schluessel.length();
			for(int i = 0; i<keylength; i++) {
				if((schluessel.indexOf(""+i)==-1) || (schluessel.lastIndexOf(""+i) != schluessel.indexOf(""+i))) {
					return false;
				}
			}
		}
		
		return true;
	}
	//die Deocodierung des bildes mit speichern der Zeichen in temp2 und übergabe von decoded
	static String decode(String bild, String schluessel)
	{
		String decoded = "";
		int keylength = schluessel.length();
		for(int i = 0; i < (bild.length()/keylength); i++) {
			String temp = bild.substring(i*keylength, (i*keylength)+keylength);
			char []temp2 = new char[temp.length()];
			
			for(int j = 0; j < keylength; j++) {
				temp2[j] = temp.charAt(Integer.valueOf(""+schluessel.charAt(j)));
			}
			decoded += new String(temp2);
		}
		return decoded;
	}
	
	//END
	
}

also es geht alles bis auf die Zeile: 44

warum steigt er in der vorheringen if-Schleife ned aus?

der counter is bei dem Bild ungleich 0!!!

gruss und danke für deine Antwort
 
> der counter is bei dem Bild ungleich 0!!!
falsch, drei Ausrufezeichen helfen auch nicht,
schreib davor eine Zeile
> System.out.println("gleich kommt die if-Abfrage, die keine Schleife ist, counter ist aktuell "+counter);
und schon siehst du dass counter davor dann doch 0 ist, zumindest zu diesem Zeitpunkt

auf ähnliche Weise kannst du den kompletten Programmablauf nachvollziehen, wann immer dir etwas unklar ist
 
Hey dank euch ;D

also hab das mit den System.out.println - Abfragen gemacht und hab den counter nun richtig eingestellt ;D

eine andere Frage:

Warum geht das nicht?
Java:
if((bildlaenge % schluessel.length()) != 0){
			System.out.println("INVALID KEY");
			return;
		}

er wirft mir immer zurück, dass ich da kein return machen darf... warum ned?

btw der code steht in einer static methode...

gruss
 
Zuletzt bearbeitet:
wer ist 'er' und was genau wirft 'er zurück, was heißt hier eigentlich 'werfen',
erhälst du vom Compiler eine Fehlermeldung? 😉

das passt kaum zum vorherigen Code, welcher erfolgreich kompiliert und den du anscheinend auch schon ausgeführt hast,
neue Compilerfehler deuten auf Programmänderungen hin, jede falsche Klamme 100 Zeilen vorher oder später kann das gesammte Gefüge auseinanderbrechen,

ein return; in einer Methode mit Rückgabewert wäre auch nicht so schön
 
also zum SOURCE:

Java:
import java.util.*;//alles importieren was in dem util-Verzeichnis steht
public class AsciiShop {
	
	
	public static void main(String[] args) {// der Hauptteil des Porgramms
		
		Scanner sc = new Scanner(System.in);
		
		String bild = "";
		String zeile= "";
		int zeilenanzahl = 0;
		int counter = 0;
		int breite = 0;
		String schluessel = "";
		
		//1.Anforderungen überprüfen & einlesen falls es passt
		if(sc.next().equals("read") && sc.hasNextInt()) {
			zeilenanzahl = sc.nextInt();
			//counter = zeilenanzahl;
			sc.nextLine();
			
			//2. Bild einlesen und fertig machen zum decodieren
			while(sc.hasNextLine() /*&& counter>0*/) {
				zeile = sc.nextLine();
				
				if (breite == 0)//die breite wird definiert 
				{
					
					breite = zeile.length();
					//System.out.println(breite);
				} /*else {//hier ist die breite != zeile.length also:
				System.out.println("INPUT MISMATCH2");
				// WENN ICH DAS LASSE DANN WIRD INPUT MISMATCH SEHR OFT AUSGEGEBEN, WEIL NACH DEM ERSTEN DURCHLAUF DIE BREITE != 0 ist	
				}*/
				
				counter--;//counter zurücksetzten-> schleifen ausstieg
				bild += zeile;//der String wird zum bild "hinzugefügt"
				
			}
			
			if(counter == zeilenanzahl) {
				System.out.println("INPUT MISMATCH1");
				return;
			}
			
		}	
		//Fehlerabfrage bei zu wenig / zu viel Zeileneingaben
		
		else {
			System.out.println("INPUT MISMATCH2");
			return;
		}
		
		//3. decodieren und die Macht des bild-Strings bzw. einige kleine Feinheiten die noch am bild zu machen sind
		/*if(counter != 0){
		System.out.println("INPUT MISMATCH3");
		return;
		}//wird ausgegeben falls der counter ungleich 0 is
		*/
		//decode einlesen bzw. vorher überprüfe ob weiteres Zeichen einzulesen ist
		if(sc.hasNext()) {	
			zeile = sc.next();
			if(zeile.equals("decode")) {
				if(sc.hasNext()) {	//Schlüsselkontrolle + übergabe von neuem Bild
					schluessel = sc.next();
					if(checkKey(schluessel, bild.length())==true) {
						bild = decode(bild, schluessel);
					} else {
						System.out.println("INVALID KEY");
						return;
					}
				} else {
					System.out.println("INVALID KEY");
					return;
				}
			} /*else {
			System.out.println("INPUT MISMATCH4");
			}*/
		}
		
		//4.Ausgabe des entschlüsselten Bildes und FERTIG°°
		for(int i = 0; i<zeilenanzahl; i++)
		{
			
			System.out.println(bild.substring(i*breite, (i*breite)+breite));//<= here spielt sich die Action ab nach den ganzen Berechnungen^^
		}
		System.out.println(breite+ " " + zeilenanzahl);
	
	
	}	
	//3.1 - Methoden...ein kleiner abstecher was wir in 3 brauchen
	static boolean checkKey(String schluessel, int bildlaenge)//static: Das Schlüsselwort static wird immer dann verwendet, wenn die Funktionalität, die eine Methode bereitstellt, nicht für ein konkretes Objekt gilt, sondern unabhängig von Objekten bereit gestellt werden soll.
	{
		if((bildlaenge % schluessel.length()) != 0){
			System.out.println("INVALID KEY");
			return false;
		} 
		
		//ob jede Ziffer einzeln vorkommt (s.u)
		int keylength = schluessel.length();
		for(int i = 0; i<keylength; i++) {
			if((schluessel.indexOf(""+i)==-1) || (schluessel.lastIndexOf(""+i) != schluessel.indexOf(""+i))) {
				return false;
			}
		}
		
		
		return true;
	}
	//die Deocodierung des bildes mit speichern der Zeichen in temp2 und übergabe von decoded
	static String decode(String bild, String schluessel)
	{
		String decoded = "";
		int keylength = schluessel.length();
		for(int i = 0; i < (bild.length()/keylength); i++) {
			String temp = bild.substring(i*keylength, (i*keylength)+keylength);
			char []temp2 = new char[temp.length()];
			
			for(int j = 0; j < keylength; j++) {
				temp2[j] = temp.charAt(Integer.valueOf(""+schluessel.charAt(j)));
			}
			decoded += new String(temp2);
		}
		return decoded;
	}
	
	//END
	
}

es geht um die Methode checkKey ganz unten

btw er is mein Compiler ;-D

gruss
 
ein Abbruch ohne return ist undenkbar

meinst du
Java:
if (x) {
   y;
}

statt

if (!x) {
  return;
}
y;
?
 
Eine boolean Variable (z.B. boolean abbruch=false) auf true setzten und bei jedem block der danach kommt noch
Java:
if(!abbruch){
hinschreiben.
Ob das eleganter ist musst du entscheiden

3! Gewünscht? 🙂

Java:
if (!(!(!abbruch))) {

geht natürlich auch 🙂
 

Zurück
Oben