What I'm attempting to do is read a text document to pass in variables into an arraylist of shape objects that I will use to create shapes. I don't need any help with the actual drawing of the shapes, working with the arraylist, or the initial scanning setup. I thought about doing a while loop to read each word/int using the single whitespace in between as the delimiter. Where I get stuck is what exactly I should do with information I don't need. For example, I would test the line to see if it said start via an if statement. I don't need the word "picture", but I do need the character "A". It's also throwing me because I have only worked with formatted files before where each line had the same data in the same way.

I've watched a bunch of videos and looked into tutorials on parsing information in a text file, but I found they were working with a formatted file. I've worked with that before, and that makes sense to me. I feel like the right steps are to create a while loop that uses the .hasNext() to go through the file, and to use nested if statements to parse the lines. If someone wouldn't mind pointing me to a tutorial or documentation that would assist me in this, I'd be grateful. Perhaps a switch would work better to avoid a crazy amount of code, but maybe I'm thinking about this in a lame way. I inserted systemouts so I could see what things it was putting inside. I see that the following code will be an issue if it doesn't follow the same pattern. Thank you for your input!

int circX, circY, circSize;
String circName, currentInput, junk;
while (input.hasNext())
{
   currentInput = input.next();
   if (currentInput.equals("start"))
   {
        junk = input.next();
        circName = input.nextLine();
        junk = input.next(); //this line gives me an error, and if I remove, it errors at next command saying there isn't such an element
        circX = input.nextInt();
        circY = input.nextInt();
        circSize = input.nextInt();
   }
}

The text file has information such as the following:

start picture A
circle 0 100 20
circle 100 100 20
circle 50 150 20
end picture
draw picture A blue 10 10
dance picture A 10 10
erase
draw picture A red 100 100
erase
draw picture A pink 100 10

another example of a test file:

start picture A
circle 50 100 20
coloredcircle 0 100 20 green
end picture
draw picture A blue 10 10
dance picture A 30 30
erase
start picture B
rectangle 0 100 20 40
rectangle 100 100 40 20
rectangle 200 100 40 20
Sshape 55 55 55 55 55 yellow Elf
Sshape 55 25 35 45 65 red Ogre
end picture
draw picture B yellow 10 10
erase
draw picture A blue 10 10

Recommended Answers

All 10 Replies

Scanner was intended as an easy tool for beginners, but in reality it's a poor implementation, and causes more problems than it solves. Forget it.

I would just read each line of the file, then split it onto an array of words using String's split() method.
You can then use a switch on the first word (Java 7 and later) and handle the remaining words as appropriate in the different cases.

(ps " I don't need any help with the actual drawing of the shapes" - suggest you check back into that thread. A couple of posts explain why your implementation is badly broken)

your text file looks pretty ordered to me. The only place where you might need scanner for input parsing purposes is when there may be unexpected lines in-between two valid lines , or a valid line has garbage in between two valid key words. split() works there too , but then you have to put in more checks. So unless you have a dirty , unordered file , go with the split-switch method.

Also , If you do decide on using scanner , (though its a bad idea if your file is always like this) , check more into the condition for hasNext() to return false. you can say that it knows there is a wall in front of it only after it has hit it ;)

Thank you for the tips : ) Rather than using a scanner, would a bufferreader be appropriate to read in the lines? like so:

          BufferedReader in = new BufferedReader(new FileReader("C:\\Users\\Mint\\Documents\\NetBeansProjects\\LearnGraphics\\src\\learngraphics\\myHwk1InputTestFile.txt"));
            String line;
            try{
            while ((line = in.readLine()) != null)
            {

                line.split(" ");
                System.out.println(line);
            }
            in.close();
            }
            catch (Exception e)
            {
                System.err.println(e.getMessage());
            }

I have also come up with an alternative here:

          while (input.hasNext())
            {
                String str = input.nextLine();
                String[] array = str.split(" ");
                 for ( int i = 0; i < array.length; i++)
                 {
                       System.out.println(array[i]);
                 }

            } 

If I'm not mistaken, or at least in my head, wouldn't a series of if/else if statements be a lot of code? Hence the mention of the switch. I tried implementing the switch, but I'm not exactly where to insert the switch at. I was using str in the switch, which is the string I put everything into as it went into the array. I found I had to put my switch inside the while loop, but it didn't print anything except that it wasn't working(my default case). What I have so far for the switch:

                switch (str)
                 {
                    case "start": 
                    System.out.println("this is the start of the process!");
                    break;
                    case "picture":
                    System.out.println("we'll be taking variables to make a picture!");
                    break;
                    case "A":
                    System.out.println("Starting shape 'A'");
                    break;
                    case "circle":
                    System.out.println("It will be a circle");
                    break;
                default:
                 System.out.println("It's not working");
                    break;                       
                }

there is a bit that you have justify here : will the "draw" tag be always followed by picture details , if so , the pass the following split()-ed tags to a drawing function that takes them in to draw a picture , instead of having switch cases for each picture description tag.

The draw tag will always be followed by picture details. How do I know to only pull the rest of the line that has draw in it though? Just trying to pull the correct info out of the file is the proverbial monkey wrench. I believe I just came to the realization that anything I don't want will be a default case. Interesting; so like, if the case were "circle" for example, take in the rest of the the line into a call to the circle drawing class/method. Then everything else will fit into the default until it gets to the draw line. It will default on "picture" and "A", take in the remainder of the line, and pass those into the method too. Would you perhaps know of a tutorial/documentation/tips that would be good to look at?

How do I know to only pull the rest of the line that has draw in it though?

as your current txt stands , draw is always at the begining , so after split()-ing a line , check if the 1st entry equals draw , if so , you know that the rest will also be picture details.

I tried implementing the switch, ... I was using str in the switch,

The first word of each line is in the first element of the array where you split the line, so that's the string you can switch on
switch (array[0]) { ...

BufferedReader is the best way to read whole lines.

commented: Oh....haha +0

I think I have done it:

String line;
is = new FileInputStream("C:\\Users\\Mint\\Documents\\NetBeansProjects\\LearnGraphics\\src\\learngraphics\\myHwk1InputTestFile.txt");
br = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
    try {
        while ((line = br.readLine()) != null) 
        {
            // Deal with the line
            System.out.println(line);
            if(line.startsWith("circle"))
            {
                String[] parts = line.split(" ");
                 int x = Integer.parseInt(parts[1]);
                 int y = Integer.parseInt(parts[2]);
                 int k  =Integer.parseInt(parts[3]);

            }   
        }
        } catch (IOException ex) 
        {
        Logger.getLogger(TestCircle.class.getName()).log(Level.SEVERE, null, ex);
        }

// Done with the file
br.close();
br = null;
is = null;

Of course, that only works for circle, but pipes and the other shapes in the line.startsWith() should do the trick, I think.

When I tried to implement the switch version, simply just because I want to, it doesn't print out the variables x,y, or k. Not sure what's going on there. I can certainly just go with the previous code though.

          while (input.hasNext())
            {

                String line = input.nextLine();
                String[] array = new String[0];
                //String[] array = str.split(" ");
                 for ( int i = 0; i < array.length; i++)
                 {
                       System.out.println(array[i]);
                   switch (array[0])
                 {
                    case "circle":
                    System.out.println("It will be a circle");
                    String[] parts = line.split(" ");
                    int x = Integer.parseInt(parts[1]);
                    int y = Integer.parseInt(parts[2]);
                    int k  =Integer.parseInt(parts[3]);    
                    System.out.println("x =" + x + "y ="+y+"k="+k);
                    break;
                    default:
                     System.out.println("It's not working");
                        break;
                }
                 }

            } 

Ugh. One day I will be good at this Java stuff! I swear it! When I pass in the variables obtained and print out c, the circle object, it is missing the last variable. It's supposed to have: 50 150 20, but it only has 50 150.

          int circX, circY, circSize;
          String circName, currentInput, line;
          InputStream is;
          BufferedReader br;

            ArrayList<Shape> shapes= new ArrayList<Shape>();            
            Picture<Shape> pics = new Picture<Shape>("Pics With Different Shapes");



is = new FileInputStream("C:\\Users\\Mint\\Documents\\NetBeansProjects\\LearnGraphics\\src\\learngraphics\\myHwk1InputTestFile.txt");
br = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
    try {
        while ((line = br.readLine()) != null) 
        {
            // Deal with the line
            System.out.println(line);
            if(line.startsWith("circle"))
            {
                String[] details = line.split(" ");
                 int inX = Integer.parseInt(details[1]);
                 int inY = Integer.parseInt(details[2]);
                 int size = Integer.parseInt(details[3]);          
                 Circle c = new Circle("circ", inX, inY, size);
                 pics.add(c);
                 System.out.println(c);
            }   
        }
        } catch (IOException ex) 
        {
        Logger.getLogger(TestCircle.class.getName()).log(Level.SEVERE, null, ex);
        }

// Done with the file
br.close();
br = null;
is = null;
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.