sola
sola

Reputation: 147

scanner skipping new line

I am trying to understand the scanner class in java, does anyone why this code is only printing the first line in part one and not all the information in part 2.

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.util.Scanner;

public class BadParse {

public static String getNextEntry(InputStream in) {
    Scanner sin = new Scanner(in);

    try {
        String ssn = sin.next();
        String name = sin.next();
        int age = sin.nextInt();

        return name + "(" + ssn + ") is " + age + " years old.";
    } catch (NoSuchElementException e) {
        return null;
    }
}

public static void putNextEntry(String ssn, String name, int age, OutputStream out) {
    PrintWriter pout = new PrintWriter(new OutputStreamWriter(out));

    pout.print(ssn + " ");
    pout.print(name + " ");
    pout.print(age + " ");
}

public static void main(String[] args) throws IOException {

    // Part I
    String input = "1234567890 John 20\n0987654321 Beth 18\n2468101214 Jack 19\n";
    InputStream in = new ByteArrayInputStream(input.getBytes());

    String entry;
    while ((entry = getNextEntry(in)) != null) {
        System.out.println(entry);
    }

    // Part II
    OutputStream out = new FileOutputStream("data");

    putNextEntry("1234567890", "John", 20, out);
    putNextEntry("0987654321", "Beth", 18, out);
    putNextEntry("2468101214", "Jack", 19, out);

    out.close();
}

}

i tried using delimiters but to no success.

Upvotes: 1

Views: 625

Answers (2)

Marc Baumbach
Marc Baumbach

Reputation: 10473

If you run a debugger and step through the getNextEntry method, you'll see that on the second call, the Scanner throws a NoSuchElementException. The reason this is happening is because the first Scanner has consumed part of the ByteArrayInputStream.

One fix you can do is create the Scanner before your while loop and pass in the Scanner to getNextEntry instead of passing in the ByteArrayInputStream.

public static String getNextEntry(Scanner sin) {

...

Scanner sin = new Scanner(in);
String entry;
while ((entry = getNextEntry(sin)) != null) {

In terms of Part 2, the PrintWriter isn't being flushed. If you add pout.flush() to the bottom of putNextEntry that should cause data to be sent to your file. For PrintWriter objects, the data is only flushed if you call println, printf, format, or flush.

public static void putNextEntry(String ssn, String name, int age, OutputStream out) {
    PrintWriter pout = new PrintWriter(new OutputStreamWriter(out));
    pout.print(ssn + " ");
    pout.print(name + " ");
    pout.print(age + " ");
    pout.flush();
}

I would recommend creating and passing in the PrintWriter similar to the scanner, though. Reduces resources created and you can flush all the end after calling putNextEntry multiple times.

Upvotes: 2

havexz
havexz

Reputation: 9590

The problem is that you are creating Scanner object inside getNextEntry and when that object gets destroyed it closes the stream. Try passing Scanner as argument instead of stream like (and same goes for PrintWriter):

 import java.io.ByteArrayInputStream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.util.Scanner;

public class BadParse {
public static String getNextEntry(Scanner sin) {

    try {
        String ssn = sin.next();
        String name = sin.next();
        int age = sin.nextInt();

        return name + "(" + ssn + ") is " + age + " years old.";
    } catch (NoSuchElementException e) {
        return null;
    }
}

public static void putNextEntry(String ssn, String name, int age, PrintWriter pout) {

    pout.print(ssn + " ");
    pout.print(name + " ");
    pout.print(age + " ");
}

public static void main(String[] args) throws IOException {

    // Part I
    String input = "1234567890 John 20\n0987654321 Beth 18\n2468101214 Jack 19\n";
    InputStream in = new ByteArrayInputStream(input.getBytes());
    Scanner sin = new Scanner(in);

    String entry;
    while ((entry = getNextEntry(sin)) != null) {
        System.out.println(entry);
    }

    // Part II
    OutputStream out = new FileOutputStream("data");
    PrintWriter pout = new PrintWriter(new OutputStreamWriter(out));

    putNextEntry("1234567890", "John", 20, pout);
    putNextEntry("0987654321", "Beth", 18, pout);
    putNextEntry("2468101214", "Jack", 19, pout);

    pout.close();
}
} 

Upvotes: 2

Related Questions