Hi all - another "what are the expectations here?"...
# getting-started
c
Hi all - another "what are the expectations here?" question based on a question in the JetBrains' hyperskill Kotlin course. I have a question that asks: "what are the expected inputs for the following snippet of code:"
Copy code
val scanner = Scanner(System.`in`)
val s1 = scanner.nextLine()
val s2 = scanner.nextLine()
val num = scanner.nextInt()
The answers are roughly: a )
Copy code
ABC DEF
123
b )
Copy code
ABC
DEF 123
c)
Copy code
10
ABC
3
d)
Copy code
ABC DEF 123
Looking the behavior in kotlin file locally, the only answer that doesn't throw an error is
a
, but not according to the course page. Is this a Kotlin version issue? A JVM issue? Apparently the correct answer is
c
but the first Int is confusing me. Any hints or clarity would be most appreciated! Thank you!
j
readLine()
can read any text, it doesn't have to be letters. Since we don't see the rest of the program it could really be anything
c
@Joffrey thanks for the response! That makes sense, looking at the docs for
readLine()
but
nextLine()
only seems to applicable to strings?
j
My bad I meant
nextLine
. Strings can be anything including numbers
p
"10"
is still a string 😉
c
@phldavies thank you! I'm surprised - I was certain that there was a difference between
10
and
"10"
- first is an Int and the second is a String, but that's wrong?
10
is a string, unless it is explicitly typed?
v
But how would A work? The only sensible answer is C.
nextLine
reads a line,
nextInt
reads an int, so it has to be three lines and the only option with that is C.
Regarding
10
vs
"10"
, coming as input the first is a two character string, the latter is a four character string. The quotes are just significant when writing a string literal in source code
âž• 1
c
@Vampire hi there. As I mentioned, I suppose I was confused by two things. Firstly, C looks like int, string, int, and secondly,
nextLine
talks about strings. Glad to learn that quotes are only significant in literals in source code - not in input for the
scanner
example.
p
We’re talking here about reading from an input stream using a
Scanner
. in this case, the input stream is the following:
Copy code
10\n
ABC\n
3
(I’ve added
\n
to highlight the line endings).
Scanner.nextLine()
is reading the characters if the input stream until the next
\n
and returning the string value. In this case it’s returning the
String
of
"10"
- this is still nothing to do with the Kotlin representation of string vs integer in the code. The two calls to
nextLine()
each advance the scanner to after the
\n
. Starting with
Copy code
|10\n
 ABC\n
 3
then after one call to
nextLine()
Copy code
10\n
|ABC\n
 3
and finally after the second call to
nextLine()
Copy code
10\n
 ABC\n
 3
Then the call to
nextInt()
reads the next token (by default delimited by whitespace) and then interprets this value as an integer.
c
@phldavies yes, I'm almost there. I'm probably too focused on types at this point - I appreciate your (and @Vampire's) clarifications.
👌 1
I apologize if I seem like I'm belaboring this -- I'm wondering what to expect when I run this locally:
Copy code
import java.util.Scanner

fun main() {
    println("hello - let's go explore!")

    val scanner = Scanner(System.`in`)
    val s1 = scanner.nextLine()
    val s2 = scanner.nextLine()
    val num = scanner.nextInt()

    println(s1)
    println(s2)
    println(num)
}
I'm running this in IntelliJ 2022.1.1, with OpenJDK 11, and Kotlin 221-1.6.21-release. I can enter:
Copy code
10\n
abc\n
and then an error is thrown:
Copy code
Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(Scanner.java:939)
	at java.base/java.util.Scanner.next(Scanner.java:1594)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
	at ExploreKt.main(explore.kt:9)
	at ExploreKt.main(explore.kt)
y
Basically, if you're reading from a Scanner or any form of input stream, you're taking in bytes of information. Usually, and especially in the case of
<http://System.in|System.in>
, those bytes are interpreted as Strings. So when you call
nextInt
, the Scanner interprets the bytes as a string first, checks that they're a valid int, and if that string parses to a valid int, it is simply returned to you.
In other words,
nextInt
is similar to
next
followed by a
Integer.parseInt
, and so every integer you read from a console, file, or any other ASCII-formatted thing will be first and foremost a valid string before it is an int
v
That's overly simplified though, as it also does things like removing group separators, locale-specific prefixes and so on.