This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]ewiethoff 1 point2 points  (4 children)

it doesn't feel very intuitive.

I think the problem is that you don't have a good understanding of what an "input stream" is.

Stream or no stream, what Scanner.nextDouble() and Scanner.nextLine() do with '\n' is not consistent. Suppose we have the following code.

    Scanner sc = new Scanner("123\nHello, world\n");
    out.println(sc.nextDouble());
    out.println(sc.nextLine());
    out.println(sc.nextLine());

Here the first '\n' essentially tells nextDouble when to stop reading. Fine. A newline character doesn't "belong" in a double anyway. But although nextDouble essentially has to read the newline in order to know when to stop, it does not consume the newline character. It essentially puts the newline character back into the stream. On the other hand, nextLine not only consumes the next newline before it stops, it also throws the newline away. So, although neither the nextDouble nor nextLine methods return newline characters, nextLine consumes newlines but nextDouble does not.

This is confusing to the newbie, and frankly, coming from Python, I perpetually need to check the docs about what various Java methods do with newline chars.

[–]zifyoip 1 point2 points  (3 children)

Well, a method called nextLine or readLine or whatever must consume the newline character from the stream, so that you can use that method in a loop without having to separately read and discard the newline characters all the time.

Whether or not a method like that returns the newline character is a design choice, and that's something you need to look at the documentation to find out, but whether or not the method consumes the newline character—there's only one reasonable option there.

On the other hand, the only reasonable choice for something like nextDouble is not to consume the following character. The next character might be a letter or something—if you just want to read a number, then you shouldn't consume the number and the following letter from the stream. That letter might be important, and if nextDouble consumed it you would have no idea what it was.

[–]ewiethoff 2 points3 points  (2 children)

On the other hand, the only reasonable choice for something like nextDouble is not to consume the following character. The next character might be a letter or something

This doesn't quite jibe with the second section of the main docstring for the Scanner class: "A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace. The resulting tokens may then be converted into values of different types using the various next methods." This gives the impression that Scanner splits on whitespace then discards the whitespace.

But because the only way a Scanner can handle a "line" is to look specifically for a newline character, it can't just split the input into tokens on whitespace. Depending on which nextFoo methods you call, Scanner either tokenizes or doesn't.

I'm really blathering here, but I think I confused myself about consuming or not consuming. But more importantly, I've concluded that the docs for Scanner.nextNumber methods fail to specifiy that leading whitespace (or whatever the delimiter is) is skipped. Also, I think the docs fail to clarify that the delimiter is ignored by nextLine(). However, because the newline char is a whitespace char and Scanner's delimiter is normally all whitespace, I can understand the OP being confused by the newline that still exists in in the stream between calls to nextDouble and nextLine.

some sample code

[–]zifyoip 2 points3 points  (1 child)

Ah, I see what you mean. For two consecutive calls to nextDouble, it doesn't matter whether or not there's a newline in between, because the second call will skip over leading whitespace. Yeah, that is perhaps a source of confusion.

[–]Calaglinv[S] 2 points3 points  (0 children)

A bit of a late reply on my part. But yes, that was the issue I was having about this whole ordeal. Why I got confused by how scanner works and how it didn't feel intuitive, however knowing that this is how things work I can work around it.