# In.readLine() wird übersprungen Eclipse



## AcE(swiss) (25. Jul 2011)

Seeervus,

habe folgendes Problem: 

Wenn ich in Eclipse Version: 3.7.0 einen String einlesen will mache ich dies normalerweise mit In.readLine() da man da ja keine Hochkommas vor und nach dem einzugebendem String eintippen muss.

Jedoch kommt es so sehr gerne vor, dass mir Eclipse die Stelle einfach überspringt.

Er gibt noch den Outprint davor aus, jedoch liest er mir keinen String ein. Ich habe dies mal meinem Dozenten gezeigt und er meinte, das käme davon, dass noch ein Leerzeile mitkommt. Aber ich habe keine Überflüssigen Entertasten-Schläge drinn.

Temporär habe ich das Problem mit In.readString() gelöst, obwohl das sehr unangenehm ist, immer die Hochkommas eingeben zu müssen.

Ist das Problem bekannt?

hoffe ihr könnt mir helfen.

freundliche Grüsse

Dominic


KONKRETES BEISPIEL:

Das programm startet in der Mai und ruft die Methode startGame() auf, danach kommt eig. als erstes die Frage bezüglich des Busts, die überhüpft wird..


```
a = new BlackJack();
			a.startGame();
		}
	}
```

UND


```
//////////////////////////////////////////// SPIEL START ////////////////////////////////////////////////////	
	
	Hand startGame(){
		
		Karten.Herz_Ass.wert = 11;
		Karten.Karo_Ass.wert = 11;
		Karten.Kreuz_Ass.wert = 11;
		Karten.Pik_Ass.wert = 11;
		
		System.out.println("Bust setzen?");
		
		if (In.readLine().contains("j")) {

			System.out.println("Hoehe des Busts?");
			bust = In.readInt();
			Bust = true;
		}
```


----------



## XHelp (25. Jul 2011)

Was ist überhaupt In? Was genau wird ausgegeben und welche Stelle wird übersprungen? Was erwartest du denn sonst? Was gibst du ein?
P.S. 
	
	
	
	





```
bust
```
 vs 
	
	
	
	





```
Bust
```
, du kannst mir nicht erzählen, dass du selber noch nie da durcheinander bekommen bist.


----------



## Gelöschtes Mitglied 5909 (25. Jul 2011)

was ist denn bitteschön die Klasse "In". In der Standard API ist das definitiv nicht, warscheinlich irgendein zeug von dem Dozenten


----------



## Volvagia (25. Jul 2011)

Davon abgesehen erzeugst du eine Instanz und greifst dann auf eine statische Variable zu? 
Und das mit Karten.Herz_Ass.wert ist mir auch schleierhaft, und definitiv vom Namen her falsch. Habt ihr in den Jahr in dem ihr jetzt mindestens Java habt etwas richtig gelernt?


----------



## AcE(swiss) (25. Jul 2011)

@XHelp:
Was übersprungen wird: bust = In.readLine();
Was ich erwarte: das er mir den String den ich eingeben möchte in die variable bust speichert.
Was ich eingebe: gar nichts, denn die Stelle wird übersprungen.
Bezüglich Durcheinander:  nein hab ich nicht, da ich die beiden Variablen mitleriweile schon so lange angestarrt habe, dass ich sie blind unterscheiden kann. Zugegeben, die Benamslung weisst gewisse Defizite auf 

@raiL:

Nein, ich musste mir In.class & out.class in einen separaten In&Out ordner werfen. Die sind doch wohl bekannt? Wie liest du denn Werte ein? 

@Volvagia: Da ich das Spiel wiederhole bis ich kein Geld mehr hab, initialisier ich die 4 Asse wieder mit ihren Werten 11, da es schon vorkam, dass die erste gezogene Karte ein Ass wahr, und sie den Wert 1 hatte.
(da ich jene Werte der Asse auf 1 setze, falls die Hand des Spielers oder Croupiers grösser 11 ist)

Ich denk schon dass ich etwas gelernt habe, wieso meinst du?


----------



## XHelp (25. Jul 2011)

Irgendwelche "In" und "Out" sind weit verbreitet in engen Kreisen, und davon gibt es gefühlte 100000 Implementierungen. Auf die Frage was du für ein Auto fährst, wirst du ja auch (hoffentlich) nicht "ein rotes" antworten. Also: nein, die Klassen sind uns unbekannt, die Eingabe erfolgt auf eine sinvollere Art und Weise, so wie in den meisten Büchern beschrieben wird.

Pack dir ganz viele 
	
	
	
	





```
System.out.println
```
 rein und versuche anhand von diesen den Ablauf anzuschauen. Dann sollte dir klar sein, was wieso und wann übersprungen wird


----------



## Gelöschtes Mitglied 5909 (25. Jul 2011)

such dir eine variante aus:


```
public static String readLine() {
		return new Scanner(System.in).nextLine();
	}

	public static String readLine2() {
		return System.console().readLine();
	}

	public static String readLine3() throws IOException {
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(System.in));
			return reader.readLine();
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (IOException e) {
				// ignore
			}
		}
	}
```


----------



## Volvagia (25. Jul 2011)

99 % in der Regel wird Scanner zum Lesen von Eingaben in der Konsole (vermutlich weil er keine checked Exceptions wirft) und FileReader/-InputStream, eventuell in einen Bufferer verpackt für alles andere genutzt.
Aber wer Variablenamen groß schreibt wird in der Regel gelyncht, das sollte man als allererstes lernen.

Du solltest übrigens nicht so schreiben, wie du es lesen kannst, sondern wie andere es mindestens genauso gut lesen können.


----------



## AcE(swiss) (25. Jul 2011)

Habe als Ausbildungsgrundlage das Buch "Sprechen Sie Java?" von Mössenböck. In diesem Buch wird die Philosophie mit den In & outs gepflegt..

Wieso ist diese Art nicht sinnvoll?

Bin schon länger am debuggen und wenn In.readLine() steht, geht er mir schlichtweg nicht in die If() rein. bei In.readString() jedoch schon.. ???:L

@Volvagia: Danke, ich werds in Zukunft berücksichtigen  Bitte beachtet, ich habe erst seit einem halben Jahr java, und dies auch nur bis und mit Klassen. Den Rest bringe ich mir gerade selber bei.

Ausserdem ist es ja auch nur ein Auschnitt aus dem Ganzen, da ist es doch klar, dass man nicht sieht für was jener oder anderer Befehl gut ist. Ich post doch aber auch nicht das Ganze Spiel grad um ein Problem mit dem Einlesen, welches ja schon von Beginn weg besteht, zu beheben. 

@raiL: ok danke, ich werds mir mal in Ruhe ansehen!


----------



## XHelp (25. Jul 2011)

AcE(swiss) hat gesagt.:


> Bin schon länger am debuggen und wenn In.readLine() steht, geht er mir schlichtweg nicht in die If() rein. bei In.readString() jedoch schon.. ???:L



Dann guck einfach nach, was er überhaupt einließt?


----------



## Gelöschtes Mitglied 5909 (25. Jul 2011)

poste mal den code von In/Out, keine Ahnung was der Autor deines Ausblidungsbuches da so macht


----------



## AcE(swiss) (25. Jul 2011)

In.readLine():


```
public static String readLine() {
  StringBuffer b = new StringBuffer();
  char c = read();
  while (done && c != LS[0]) {
    b.append(c);
    c = read();
  }

  int i = 0;
  while (c == LS[i]) {
    ++i;
    if (i >= LS.length) { break; }
    c = read();
  }

  if (i < LS.length) {
    buf = c;
  } else {
    buf = empty;
  }
  if (b.length() > 0) done = true;
  return b.toString();
}
```

Klasse In:

```
public class In {

/** End of file indicator returned by read() or peek() when no more
characters can be read.
*/
public  static final char eof   = '\uffff';

private static final int empty = '\ufffe';

private static final char eofChar = '\u0005';  // ctrl E
private static InputStream in;
private static LinkedList inputStack, bufferStack;
private static boolean done; // true if recent operation was successful
private static char buf;     // last read character
private static char[] LS;    // line separator (eol)

private static char charAfterWhiteSpace() {
  char c;
  do c = read(); while (done && c <= ' ');
  return c;
}

private static String readDigits() {
  StringBuffer b = new StringBuffer();
  char c = charAfterWhiteSpace();
  if (done && c == '-') {
    b.append(c);
    c = read();
  }
  while (done && Character.isDigit(c)) {
    b.append(c);
    c = read();
  }
  buf = c;
  return b.toString();
}

private static String readFloatDigits() {
  StringBuffer b = new StringBuffer();
  char c = charAfterWhiteSpace();
  if (done && (c == '+' || c == '-')) {
    b.append(c);
    c = read();
  }
  while (done && Character.isDigit(c)) {
    b.append(c);
    c = read();
  }
  if (done && (c == '.')) {
    b.append(c);
    c = read();
    while (done && Character.isDigit(c)) {
      b.append(c);
      c = read();
    }
  }
  if (done && (c == 'e' || c == 'E')) {
    b.append(c);
    c = read();
    if (done && (c == '+' || c == '-')) {
      b.append(c);
      c = read();
    }
    while (done && Character.isDigit(c)) {
      b.append(c);
      c = read();
    }
  }
  buf = c;
  return b.toString();
}


/** Read a raw character (byte).
If an attempt is made to read beyond the end of the file,
eof is returned and done() yields false. Otherwise the read byte
is in the range 0..255.
*/
public static char read() {
  char c;
  if (buf != empty) {
    c = buf;
    if (buf != eof) buf = empty;
  } else {
    try {
      c = (char)in.read();
    } catch (IOException e) {
      done = false;
      c = eof; buf = eof;
    }
  }
  if (c == eofChar && inputStack.size() == 0) { c = eof; buf = eof; }
  done = c != eof;
  return c;
}

/** Current available raw characters.
In case of an error 0 is returned and done() yields false.
*/
public static int available() {
  int avail;

  try {
    avail = in.available();
  } catch(IOException exc) {
    avail = 0;
    done = false;
  }

  return avail;
}

/** Read a character, but skip white spaces (byte).
If an attempt is made to read beyond the end of the file,
eof is returned and done() yields false. Otherwise the read byte
is in the range 0..255.
*/
public static char readChar() {
  return charAfterWhiteSpace();
}

/** Read a boolean value.
This method skips white space and tries to read an identifier. If its value
is "true" the method returns true otherwise false. If the identifier is neither
"true" nor "false" done() yields false.
*/
public static boolean readBoolean() {
  String s = readIdentifier();
  done = true;
  if (s.equals("true")) return true;
  else { done = s.equals("false"); return false; }
}

/** Read an identifier.
This method skips white space and tries to read an identifier starting
with a letter and continuing with letters or digits. If a token of this
structure could be read, it is returned otherwise the empty string is
returned and done() yields false.
*/
public static String readIdentifier() {
  StringBuffer b = new StringBuffer();
  char c = charAfterWhiteSpace();
  if (done && Character.isLetter(c)) {
    b.append(c);
    c = read();
    while (done && (Character.isLetter(c) || Character.isDigit(c))) {
      b.append(c);
      c = read();
    }
  }
  buf = c;
  done = b.length() > 0;
  return b.toString();
}

/** Read a word.
This method skips white space and tries to read a word consisting of
all characters up to the next white space or to the end of the file.
If a token of this structure could be read, it is returned otherwise
an empty string is returned and done() yields false.
*/
public static String readWord() {
  StringBuffer b = new StringBuffer();
  char c = charAfterWhiteSpace();
  while (done && c > ' ') {
    b.append(c);
    c = read();
  }
  buf = c;
  done = b.length() > 0;
  return b.toString();
}

/** Read a line of text.
This method reads the rest of the current line (including eol) and
returns it (excluding eol). A line may be empty.
*/
public static String readLine() {
  StringBuffer b = new StringBuffer();
  char c = read();
  while (done && c != LS[0]) {
    b.append(c);
    c = read();
  }

  int i = 0;
  while (c == LS[i]) {
    ++i;
    if (i >= LS.length) { break; }
    c = read();
  }

  if (i < LS.length) {
    buf = c;
  } else {
    buf = empty;
  }
  if (b.length() > 0) done = true;
  return b.toString();
}

/** Read the whole file.
This method reads from the current position to the end of the
file and returns its text in a single large string. done() yields
always true.
*/
public static String readFile() {
  StringBuffer b = new StringBuffer();
  char c = charAfterWhiteSpace();
  while (done) {
    b.append(c);
    c = read();
  }
  buf = eof;
  done = true;
  return b.toString();
}

/** Read a quote-delimited string.
This method skips white space and tries to read a string in the form "...".
It can be used to read pieces of text that contain white space.
*/
public static String readString() {
  StringBuffer b = new StringBuffer();
  char c = charAfterWhiteSpace();
  if (done && c == '"') {
    c = read();
    while (done && c != '"') {
      b.append(c);
      c = read();
    }
    if (c == '"') { c = read(); done = true; } else done = false;
  } else done = false;
  buf = c;
  return b.toString();
}

/** Read an integer.
This method skips white space and tries to read an integer. If the
text does not contain an integer or if the number is too big, the
value 0 is returned and the subsequent call of done() yields false.
An integer is a sequence of digits, possibly preceded by '-'.
*/
public static int readInt() {
  String s = readDigits();
  try {
    done = true;
    return Integer.parseInt(s);
  } catch (Exception e) {
    done = false; return 0;
  }
}

/** Read a long integer.
This method skips white space and tries to read a long integer. If the
text does not contain a number or if the number is too big, the
value 0 is returned and the subsequent call of done() yields false.
A long integer is a sequence of digits, possibly preceded by '-'.
*/
public static long readLong() {
  String s = readDigits();
  try {
    done = true;
    return Long.parseLong(s);
  } catch (Exception e) {
    done = false; return 0;
  }
}

/** Read a float value.
This method skips white space and tries to read a float value. If the
text does not contain a float value or if the number is not well-formed,
the value 0f is returned and the subsequent call of done() yields false.
An float value is as specified in the Java language description. It may
be preceded by a '+' or a '-'.
*/
public static float readFloat() {
  String s = readFloatDigits();
  try {
    done = true;
    return Float.parseFloat(s);
  } catch (Exception e) {
    done = false; return 0f;
  }
}

/** Read a double value.
This method skips white space and tries to read a double value. If the
text does not contain a double value or if the number is not well-formed,
the value 0.0 is returned and the subsequent call of done() yields false.
An double value is as specified in the Java language description. It may
be preceded by a '+' or a '-'.
*/
public static double readDouble() {
  String s = readFloatDigits();
  try {
    done = true;
    return Double.parseDouble(s);
  } catch (Exception e) {
    done = false; return 0.0;
  }
}

/** Peek at the next character.
This method skips white space and returns the next character without removing
it from the input stream. It can be used to find out, what token comes next
in the input stream.
*/
public static char peek() {
  char c = charAfterWhiteSpace();
  buf = c;
  return c;
}

/** Open a text file for reading
The text file with the name fn is opened as the new current input
file. When it is closed again, the previous input file is restored.
*/
public static void open(String fn) {
  try {
    InputStream s = new FileInputStream(fn);
    bufferStack.add(new Character(buf));
    inputStack.add(in);
    in = s;
    done = true;
  } catch (FileNotFoundException e) {
    done = false;
  }
  buf = empty;
}

/** Close the current input file.
The current input file is closed and the previous input file is
restored. Closing the keyboard input has no effect but causes
done() to yield false.
*/
public static void close() {
  try {
    if (inputStack.size() > 0) {
      in.close();
      in = (InputStream) inputStack.removeLast();
      buf = ((Character) bufferStack.removeLast()).charValue();
      done = true;
    } else {
      done = false; buf = empty;
    }
  } catch (IOException e) {
    done = false; buf = empty;
  }
}

/** Check if the previous operation was successful.
This method returns true if the previous read operation was able
to read a token of the requested structure. It can also be called
after open() and close() to check if these operations were successful.
If done() is called before any other operation it yields true.
*/
public static boolean done() {
  return done;
}

static { // initializer
  done = true;
  in = System.in;
  buf = empty;
  inputStack = new LinkedList();
  bufferStack = new LinkedList();
  LS = System.getProperty("line.separator").toCharArray();
  if (LS == null || LS.length == 0) {
    LS = new char[] { '\n' };
  }
}

}
```

so wies ausschaut einfach die sammlung von In.readLine(), In.readInt() usw. usw.

hab jetz mal mit dem Debugger die In.readLine() durchgeguckt und wies ausschaut fliegt er bei der while (done && c != LS[0]) { raus in die  while (c == LS_) {_


----------



## Volvagia (25. Jul 2011)

Warum verwendest (versuchst) du nicht einfach read()? Ein char ist ja genau das was du willst. (Lass dich von den Blödsinn in dem Javadoc-Kommentar nicht verwirren, ein signed byte ist 1 und ein char 2 bytes lang.)


----------



## Gelöschtes Mitglied 5909 (25. Jul 2011)

das mit dem done ist witzig und dann auchnoch jedes zeichen einzeln lesen, aber naja ist ja nur console


----------



## AcE(swiss) (25. Jul 2011)

habs mal mit In.read() probiert:


```
System.out.println("Bust setzen?");
		
		if (In.read() == 'j') {

			System.out.println("Hoehe des Busts?");
			bust = In.readInt();
		}
		System.out.println("Test");
		char z = In.read();
		System.out.println(z);
```

aber auch hier, er geht wohl in die methode read(), fliegt aber wieder raus und gibt mir bei z sogar ne zeile aus.. hä?!


----------



## Volvagia (25. Jul 2011)

Eine Zeile kann er dir nur schwer zurückgeben. Außer die Zeile besteht genau aus '\n'. Vergiss bitte den Blödsinn und verwende einen gescheiten Scanner oder auch das System.console();.


----------



## AcE(swiss) (25. Jul 2011)

ahhh drecks doppel post-.- soory


----------



## AcE(swiss) (25. Jul 2011)

eine Zeile? er soll mir ja den eingelesenen Char zurückgeben, und das ist ja keine \n sondern j
hab aber gerade festgestellt, dass wenn ich bei In.read() j eingeben kann ich bei In.readLine() eingeben was ich möchte, er gibt mir immer den unter In.read() eingelesenen Wert zurück..


```
System.out.println("Bust setzen?");
        
        if (In.read() == 'j') {
 
            System.out.println("Hoehe des Busts?");
            bust = In.readInt();
        }
        System.out.println("Test");
        String z = In.readLine();
        System.out.println(z);
```

Tut mir leid, ich kenne nur diese In. methoden um Strings ein zulesen. Abgesehen die von dir aufgezählten, von mir noch nicht restlos begriffenen Optionen. Werd sie mir mal vornehmen jetzt..


----------



## Atze (25. Jul 2011)

wenn In eine klasse deines dozenten ist und du nicht weißt was drin ist, wird es schwierig dazu was zu sagen. es muss ja kein bufferedreader sein.

vielleicht verbirgt sich dahinter auch eine Console, und gab es damit in eclipse nicht mal probleme?

sollte ihr das überhaupt in eclipse programmieren?


----------



## Gelöschtes Mitglied 5909 (25. Jul 2011)

das hier sollte alles sein was du brauchst


```
public static String readLine() {
		return new Scanner(System.in).nextLine();
	}
	
	public static int readInt() {
		return new Scanner(System.in).nextInt();
	}
```


----------



## AcE(swiss) (25. Jul 2011)

Atze hat gesagt.:


> wenn In eine klasse deines dozenten ist



Es ist eine von Mössenböck 



Atze hat gesagt.:


> sollte ihr das überhaupt in eclipse programmieren?


warum nicht? Die Entwicklungsumgebung find ich an sich ganz praktisch. kenn mich da aber nicht aus!


@raiL:

He danke! Jetzt funzen alle In.readLine() bis auf den ersten, der wird seltsamer weise konsequenz übersprungen. egal -.-

EDIT: Oder auch nicht, gewisse In.readLines() werden munter überlesen... ahhh ;(


----------



## Atze (25. Jul 2011)

AcE(swiss) hat gesagt.:


> Es ist eine von Mössenböck


ach so, von mössenböck! dann ist ja alles gut ... 


> warum nicht? Die Entwicklungsumgebung find ich an sich ganz praktisch. kenn mich da aber nicht aus!


ja genau darum nicht!  wenn du klassen verwendest, die der werte herr mössenböck in die tasten gerotzt hat und nicht weiß was diese machen kannst du auch von problemen überrascht werden, von denen du nicht weißt warum sie machen was sie machen. 

wie gesagt, ich meine unter eclipse gab es imho mal schwierigkeiten mit der java6 Console. vielleicht steckt sie ja in deiner klasse In. mehr wollte ich damit nicht sagen. hast du (zumindest testweise) mal einen der vorschläge der anderen hier mal ausprobiert?


----------



## AcE(swiss) (25. Jul 2011)

Ich glaube, dass mit den Problemen von denen ich nicht weißt warum sie machen was sie machen, triffts hier wohl auf den Punkt..^^

Mössenböck ist dir ein Begriff?

aber was will ich machen, ich kann nur das anwenden was mir in der Schule bei gebracht wird, resp. was im Lehrmittel steht (was leider ein Abklatsch vom Mössenböck ist-.-) Ich les ja schon ab und zu was anderes, aber so, auf-den-ersten-blick-grad-nicht-verstandene-Einlese-Methoden vergass ich halt ganz schnell wieder, da die In.readLine()/In.readString() für die Aufgaben in der Schule bis jetzt locker ausreichten. Nur hat da auch keiner Verlangt Blackjack zu programmieren 

Ja natürlich, hab die In.read() Variante von Volvagia und die In.readLine() Version von raiL probiert.

EEEDIT: Also hab da ne brauchbare Lösung gefunden: In.readWord() 

damit klappt alles wunderbar, keine "", kein überhüpfen. tiptop  Danke nochmals für eure Hilfe!!:toll:

bisn' andermal


----------



## Gelöschtes Mitglied 5909 (26. Jul 2011)

meine version hat nix mit deiner klasse In zu tun


----------



## Atze (26. Jul 2011)

nein, ich weiß nicht wer mössenböck ist. ich wollte halt nur sagen, dass er dort vielleicht was "wrapped", das die fehler verursacht.

aber schön dass es letztendlich funzt!


----------

