problem mit schleife

Status
Nicht offen für weitere Antworten.

java666

Aktives Mitglied
Hallo,

hab ein kleines Problem!

Und zwar das die schleife mich nach dem ersten durchlauf raus haut!

Code:
import java.io.*;
import java.util.*;
/**
 *
 * @author martin
 */
public class Quiz 
{
    public static void main(String [] args)throws Exception 
    {
        FileReader dateiStream=new FileReader("/home/martin/Quiz.txt");
        BufferedReader eingabe=new BufferedReader(dateiStream);
        //Anzahl der Einträge lesen
        String zeile;
        int anzahl;
        
        zeile=eingabe.readLine();
        anzahl=Integer.parseInt(zeile);
        //Eine zufallszahl zwischen 1 und anzahl
        Random zufall=new Random();
        int zufallszahl;
        
        while(true)
        {
            zufallszahl=zufall.nextInt(anzahl+1);
            if(zufallszahl!=0)
                break;
        }
        while (true)
        {
        // die gewürfelte Zeile einlesen
        for(int i=1;i<=zufallszahl;i++)
            zeile=eingabe.readLine();
        
        // Land und Hauptstadt extrahieren
        StringTokenizer st=new StringTokenizer(zeile);
        String land=st.nextToken();
        String hauptstadt=st.nextToken();
        String hauptstadt1=st.nextToken();
        
        System.out.println("Hauptstadt von "+land+": ");
        Scanner tastatur=new Scanner(System.in);
        String antwort=tastatur.nextLine();
        
        if (antwort.equals(hauptstadt))
        {
            System.out.println("Die Antwort ist richtig!");}     
        else if (antwort.equals(hauptstadt1)){        
            System.out.println("auch richtig!");
        }
        else
            System.out.println("Falsch. Richtig ist "+hauptstadt);
                break;
        
        }
        eingabe.close();
                       
    }        
}

also die schleife für das Programm selber und nicht die für die zufallszahl!
 
ein else ohne Klammern gilt nur für eine Zeile,
break; wird in jedem Falle ausgeführt

--------

NIE if, else, Schleifen oder sonstiges ohne Klammern!


if(zufallszahl!=0)
break;

in der (noch) funktionierenden Zufallszahl-Schleife ist genauso schlimm
 
ich hab jetzt klammern gesetzt aber leider geht es nicht weiter und bring jetzt auch eine fehlermeldung!

Code:
Hauptstadt von Deutschland: 
berlin
auch richtig!
Exception in thread "main" java.lang.NullPointerException
        at java.util.StringTokenizer.<init>(StringTokenizer.java:182)
        at java.util.StringTokenizer.<init>(StringTokenizer.java:219)
        at java_buch.Quiz.main(Quiz.java:46)
Java Result: 1
ERSTELLEN ERFOLGREICH (Gesamtzeit: 0 Minuten 3 Sekunden)
und zeile 46:

Code:
StringTokenizer st=new StringTokenizer(zeile);


und hier noch die änderung in der schleife:

Code:
while (true)
        {
        // die gewürfelte Zeile einlesen
        for(int i=1;i<=zufallszahl;i++)
            zeile=eingabe.readLine();
        
        // Land und Hauptstadt extrahieren
        StringTokenizer st=new StringTokenizer(zeile);
        String land=st.nextToken();
        String hauptstadt=st.nextToken();
        String hauptstadt1=st.nextToken();
        
        System.out.println("Hauptstadt von "+land+": ");
        Scanner tastatur=new Scanner(System.in);
        String antwort=tastatur.nextLine();
        
        if (antwort.equals(hauptstadt))
        {
            System.out.println("Die Antwort ist richtig!");
        }     
        else if (antwort.equals(hauptstadt1))
        {        
            System.out.println("auch richtig!");
        }
        else
        {
            System.out.println("Falsch. Richtig ist "+hauptstadt);
                break;                
        }
                    
        }

ich hoffe damit kann man was anfangen
 
tja, das break war ein interessanter Fehler,
aber ich persönlich haue jetzt gleich wieder ab, wenn du zu 'ich denke gar nicht mehr nach sondern überlasse alles dem Forum' übergehst

analysiere dein Programm, dass ist der ganze Zauber,
was ist zeile, wird die eingelesen? (in einer for-Schleife ohne Klammern..!),
wird das einlesen überhaupt durchgeführt, was genau kommt da rein?,
was ist zufallszahl usw,

pflastere dein Programm mit
System.out.println(x ist y);
System.out.println(jetzt kommt Befehl z);
System.out.println(Schleife a fängt an/ ist in Runde b);
usw.
zu, ohne kommst du nicht weit
 
SlaterB hat gesagt.:
NIE if, else, Schleifen oder sonstiges ohne Klammern!

aber nur, wenn man nach code-zeilen bezahlt wird 😉

aber für den anfang sollte man das einhalten, was er da schrob... der übersichtlichkeit halber
 
was steht in deiner Quiz.txt drinne?
da Du alles in der letzten while Schleife abhandelst, vermute ich mal, dass das Problem ist, dass der InputStream, der die Zeilen liest wieder zurück auf den Dateianfang gesetzt werden muss.

Sonst liest Du im erst Durchgang x mal mit readline bis Zufallszahl erfüllt und im zweiten durchgang geht readline von da aus weiter, wo es beim letzten Mal geendet hat. So ist ja gar nicht gewärleistet, dass es die Zeilen noch gibt, die Du einlesen möchtest 😉
 
meinst du mich?
ich meinte das break;-Problem mit der vergessenen Klammer vom Anfang des Threads
 
ich hab kein plan wie ich des machen soll. ich hab es durch gelesen aber es kommt mir auch keine idee dadurch!
 
ich hab jetzt noch eine Methode mit rein genommen aber auch da haut des ned hin!

Code:
public class Quiz 
{
     public String readLine()throws IOException
            {
                
            }
    public static void main(String [] args)throws Exception 
    {
        FileReader dateiStream=new FileReader("/home/martin/Quiz.txt");
        BufferedReader eingabe=new BufferedReader(dateiStream);
        //Anzahl der Einträge lesen
        String zeile;
        int anzahl;
        
        zeile=eingabe.readLine();
        anzahl=Integer.parseInt(zeile);
        //Eine zufallszahl zwischen 1 und anzahl
        Random zufall=new Random();
        int zufallszahl;
        
        while(true)
        {
            zufallszahl=zufall.nextInt(anzahl+1);            
            if(zufallszahl!=0){
                break;}
        }
        while (true)
        {             
        // die gewürfelte Zeile einlesen
        for(int i=1;i<=zufallszahl;i++)
        {
            zeile=eingabe.readLine();
            
            
        }
        
        // Land und Hauptstadt extrahieren
        StringTokenizer st=new StringTokenizer(zeile);        
        String land=st.nextToken();
        String hauptstadt=st.nextToken();
        String hauptstadt1=st.nextToken();        
        
        System.out.println("Hauptstadt von "+land+": ");
        Scanner tastatur=new Scanner(System.in);
        String antwort=tastatur.next();
        
        if (antwort.equals(hauptstadt))
        {
            System.out.println("Die Antwort ist richtig!");
        }     
        else if (antwort.equals(hauptstadt1))
        {        
            System.out.println("auch richtig!");
        }
        else
        {
            System.out.println("Falsch. Richtig ist "+hauptstadt);
                break;                
        }
                    
        }
        eingabe.close();
                       
    }        
}

vielleicht jetzt nochmal einen kleinen tip
 
> vielleicht jetzt nochmal einen kleinen tip

du erzählst nicht mal, was eigentlich passieren soll..
 
des problem ist immer noch das selber wie vorhin.

er geht ab und zu in die schleife haut mich dann aber nach höchstens 4 mal raus!

Und eigentlich will ja ich bestimmen wann ich aus dem programm wieder gehe!

Und wie das ganze mit dem readLine() funktionieren soll versteh ich einfach nicht ich hab es mir in der API durchgelesen aber leider ned viel verstanden davon!
 
dein Programm enthält

for(int i=1;i<=zufallszahl;i++)
zeile=eingabe.readLine();

// Land und Hauptstadt extrahieren
StringTokenizer st=new StringTokenizer(zeile);

dass es eine Exception gibt wenn zeile null ist, hast du erfahren,
nun kannst du dich nicht mehr rausreden,
nun musst du darüber nachdenken was an dieser Stelle passieren soll
'haut mich dann aber raus' ist keine vollständige Programmbeschreibung,
warum sollte es dich nicht raushauen, was sollte stattdessen passieren?
 
das programm sollte weiter gehen bis ich eine falsche eingabe mache! Statt dessen bringt er mir eine fehlermeldung:
Code:
init:
deps-jar:
Compiling 1 source file to /home/martin/Java_Buch/build/classes
compile-single:
run-single:
Hauptstadt von USA: 
washington
auch richtig!
Hauptstadt von Senegal: 
dakar
auch richtig!
Hauptstadt von Japan: 
tokio
auch richtig!
Exception in thread "main" java.lang.NullPointerException
        at java.util.StringTokenizer.<init>(StringTokenizer.java:182)
        at java.util.StringTokenizer.<init>(StringTokenizer.java:219)
        at java_buch.Quiz.main(Quiz.java:49)
Java Result: 1
ERSTELLEN ERFOLGREICH (Gesamtzeit: 0 Minuten 13 Sekunden)

leider kann ich mit der fehlermeldung nix anfangen weil ich sie nicht verstehe!
 
die Fehlermeldung heißt: zeile == null,
aber du hast ja immer noch nicht den minimalen Aufwand geleistet,
System.out.println("zeile ist: "+zeile)
davor zu schreiben,
weil du soetwas nicht tust, hast du keine Ahnung, was dein Programm gerade macht
 
lies...... und verstehe!

Code:
// die gewürfelte Zeile einlesen
        eingabe.reset();
        for(int i=1;i<=zufallszahl;i++)
        {
            zeile=eingabe.readLine();
           
           
        }

Warum das ganze? Beispiel:
Textdatei hat 10 Zeilen

Im ersten Durchlauf ergibt die Zufallszahl: 2
Es wird also zwei mal readline() durchgeführt, der Pointer steht bereits auf Zeile 3

Im nächsten Durchlauf ergibt die Zufallszahl: 3

Es wird Zeile 3, Zeile 4, Zeile 5 gelesen, letztere wird verwendet.

Warum fängt er nicht wieder bei Zeile 1 an? Weil Du den Zeiger auf der Datei nicht wieder zurückgesetzt hast. Woher soll er das also wissen 😉

Im nächsten Durchlauf ergibt die Zufallszahl 7

Es wird gelesen
Zeile 6, Zeile 7, Zeile 8, Zeile 9, Zeile 10, Zeile 11, Zeile 12

Du verstehst das Problem? Zeile 11 und 12 gibt es nicht, deswegen die NullPointerException.
Mit reset() kannst Du einen Streampointer wieder zurücksetzen, aus dem Grunde habe ich Dir den Link zur reset() Methode geschickt.
Packst Du das also vor die for Schleife, stellst Du sicher, dass Du immer bei der ersten Zeile anfängst.
 
Und abschließend: Lies Dir mal die Java Tutorials zum Thema Streams durch, damit Du überhaupt verstehst, was Du da gemacht hast.
 
ich hab das davor schon alles gemacht nur leider hat mich das nicht wirklich weiter gebracht!
Ich hab es jetzt nochmal gemacht und mir ist aufgefallen das ich noch ein gang schöner depp bin.

Damit er wieder ein neues Land suchen kann muss er über null gehen was aber nicht geht!

Code:
init:
deps-jar:
compile-single:
run-single:
zeile ist Angola Luanda luanda 1
zeile ist Kolumbien Bogota bogota 2
zeile ist USA Washington washington 3
zeile ist Schweiz Bern bern 4
zeile ist Schweden Stockholm stockholm 5
Hauptstadt von Schweden: 
stockholm
auch richtig!
zeile ist Senegal Dakar dakar 6
zeile ist Frankreich Paris paris 7
zeile ist Deutschland Berlin berlin 8
zeile ist Japan Tokio tokio 9
zeile ist null <--- verboten 0
Exception in thread "main" java.lang.NullPointerException
        at java.util.StringTokenizer.<init>(StringTokenizer.java:182)
        at java.util.StringTokenizer.<init>(StringTokenizer.java:219)
        at java_buch.Quiz.main(Quiz.java:50)
Java Result: 1
ERSTELLEN ERFOLGREICH (Gesamtzeit: 0 Minuten 17 Sekunden)

aber wie setzt ich nach jeder abfrage das ganze wieder auf die "1"?
 
dateiStream=new FileReader("/home/martin/Quiz.txt");
eingabe=new BufferedReader(dateiStream);

oder die Daten in einer Liste speichern oder in der API den passenden Befehl finden
(fällt für dich ja weg, ich mag grad auch nicht, edit: siehe MarcoBehnke 😉 )
 
wenn ich das jetzt so mache mit dem reset() dann kommt folgende Fehlermeldung:

Code:
init:
deps-jar:
compile-single:
run-single:
Exception in thread "main" java.io.IOException: Stream not marked
        at java.io.BufferedReader.reset(BufferedReader.java:485)
        at java_buch.Quiz.main(Quiz.java:42)
Java Result: 1
ERSTELLEN ERFOLGREICH (Gesamtzeit: 0 Minuten 0 Sekunden)

was soll ich damit jetzt bitte anfangen
 
wenn du was nicht verstehst, dann verwende es einfach nicht,

aber in der API bei reset() ist es (in diesem Fall zumindest) ausführlich erklärt, wenn man denn nur lesen würde..
 
des steht in der API

Code:
reset
public void reset()
           throws IOException
Resets the stream to the most recent mark. 
Overrides:
reset in class Reader
Throws: 
IOException - If the stream has never been marked, or if the mark has been invalidated

wie soll ich daraus bitte schlau werden? Ich hab davor noch nie damit gearbeitet!
 
natürlich beim FileReader schauen, aber Streams sind wirklich ein sehr hohes Thema

(edit: ok, beim BufferedReader zu marken macht mehr Sinn, dann schaut man durchaus nur dort nach,
aber dann vielleicht dort die Beschreibung der überschriebenen Operation anschauen?)

reset
public void reset()
throws IOExceptionResets the stream. If the stream has been marked, then attempt to reposition it at the mark. If the stream has not been marked, then attempt to reset it in some way appropriate to the particular stream, for example by repositioning it to its starting point. Not all character-input streams support the reset() operation, and some support reset() without supporting mark().

Throws:
IOException - If the stream has not been marked, or if the mark has been invalidated, or if the stream does not support reset(), or if some other I/O error occurs
http://java.sun.com/javase/6/docs/api/java/io/FileReader.html
->
http://java.sun.com/javase/6/docs/api/java/io/Reader.html#reset()
 
reset

public void reset()
throws IOException

Reset the stream to the most recent mark.

Overrides:
reset in class Reader

Throws:
IOException - If the stream has never been marked, or if the mark has been invalidated


mark

public void mark(int readAheadLimit)
throws IOException

Mark the present position in the stream. Subsequent calls to reset() will attempt to reposition the stream to this point.

Overrides:
mark in class Reader

Parameters:
readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. After reading this many characters, attempting to reset the stream may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.
Throws:
IllegalArgumentException - If readAheadLimit is < 0
IOException - If an I/O error occurs

Ansonsten mach es so, wie Slater es oben beschrieben hat.....

Code:
dateiStream=new FileReader("/home/martin/Quiz.txt");
eingabe=new BufferedReader(dateiStream);

Am sinnvollsten ist es aber tatsächlich die Daten einmal einzulesen

Code:
String[] zeilen = new String[anzahl];
for(int i=0;i<=zeilen;i++)
    zeilen[i]=eingabe.readLine();


und anschließen per Zufallszahl drauf zuzugreifen

Code:
zeile = zeilen[zufall.nextInt(anzahl)];
 
Danke für eure geduld und hilfe aber ich peil es einfach gerade nicht wo was hin muss usw. Aber ich werd jetzt einfach mein buch zu ende lesen und mir dann eine neues Schnappen! Irgendwann muss es ja auch was werden mit mir.
 
immer in einfachen Schritten denken,
einen BufferedReader mitten im Programm zu verwenden ist sowieso selten günstig,

einfach alle Zeilen in eine Liste laden, dann hast du ein Problem weniger,

ein solcher Stück Code ist dann vor allem in beliebigen ähnlichen Programmen unverändert wiederverwendbar
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben