Scala Command Line Input

Command line input lets your program accept data from users at runtime — either as arguments passed when the program starts, or as interactive input typed during execution. Scala provides straightforward ways to handle both cases.

Command Line Arguments

Arguments passed when running a program are captured in the args: Array[String] parameter of the main method:

// Using @main (Scala 3)
@main def greetUser(name: String, age: Int): Unit =
  println(s"Hello, $name! You are $age years old.")

// Run: scala greetUser Alice 30
// Output: Hello, Alice! You are 30 years old.

Using args Array

object Calculator:
  def main(args: Array[String]): Unit =
    if args.length < 3 then
      println("Usage: Calculator   ")
      println("Example: Calculator 10 + 5")
    else
      val num1 = args(0).toDouble
      val op   = args(1)
      val num2 = args(2).toDouble
      val result = op match
        case "+" => num1 + num2
        case "-" => num1 - num2
        case "*" => num1 * num2
        case "/" => if num2 != 0 then num1 / num2 else Double.NaN
        case _   => throw new IllegalArgumentException(s"Unknown operator: $op")
      println(f"$num1 $op $num2 = $result%.2f")

// Run: scala Calculator 15 * 4
// Output: 15.0 * 4.0 = 60.00

Safe Argument Parsing

import scala.util.Try

@main def safeCalc(args: String*): Unit =
  args.toList match
    case numStr :: Nil =>
      Try(numStr.toDouble).fold(
        _ => println(s"'$numStr' is not a valid number"),
        n => println(f"Square of $n = ${n * n}%.2f")
      )
    case Nil =>
      println("Please provide a number as argument")
    case _ =>
      println("Too many arguments — expected exactly one number")

// Run: scala safeCalc 7
// Square of 7.0 = 49.00

Reading Interactive Input with StdIn

import scala.io.StdIn

@main def interactiveGreet(): Unit =
  print("Enter your name: ")
  val name = StdIn.readLine()

  print("Enter your age: ")
  val age = StdIn.readInt()

  println(s"Hello, $name! You will be ${age + 10} in 10 years.")

// Terminal:
// Enter your name: Priya
// Enter your age: 28
// Hello, Priya! You will be 38 in 10 years.

StdIn Methods

import scala.io.StdIn

val line    = StdIn.readLine()       // reads a full line as String
val integer = StdIn.readInt()        // reads an Int
val double  = StdIn.readDouble()     // reads a Double
val boolean = StdIn.readBoolean()    // reads a Boolean (true/false)

// readLine with a prompt
val name = StdIn.readLine("What is your name? ")

Loop for Multiple Inputs

import scala.io.StdIn

@main def sumNumbers(): Unit =
  println("Enter numbers one per line. Type 'done' to finish.")
  var numbers = List.empty[Double]
  var running = true

  while running do
    val input = StdIn.readLine()
    if input.trim.toLowerCase == "done" then
      running = false
    else
      scala.util.Try(input.toDouble) match
        case scala.util.Success(n) => numbers = numbers :+ n
        case scala.util.Failure(_) => println(s"'$input' is not a number, skipping")

  if numbers.isEmpty then
    println("No numbers entered.")
  else
    println(f"Count: ${numbers.length}")
    println(f"Sum:   ${numbers.sum}%.2f")
    println(f"Avg:   ${numbers.sum / numbers.length}%.2f")

Reading a Menu Choice

import scala.io.StdIn

@main def menuApp(): Unit =
  var running = true
  while running do
    println("\n=== Menu ===")
    println("1. Say hello")
    println("2. Show date info")
    println("3. Exit")
    print("Choice: ")

    StdIn.readLine().trim match
      case "1" => println("Hello, World!")
      case "2" =>
        val now = java.time.LocalDate.now()
        println(s"Today is $now")
      case "3" =>
        println("Goodbye!")
        running = false
      case other =>
        println(s"'$other' is not a valid choice. Try 1, 2, or 3.")

Argument Defaults and Validation

object ServerLauncher:
  def main(args: Array[String]): Unit =
    val host = args.lift(0).getOrElse("localhost")
    val port = args.lift(1).flatMap(s => scala.util.Try(s.toInt).toOption).getOrElse(8080)
    val mode = args.lift(2).getOrElse("development")

    println(s"Starting server:")
    println(s"  Host: $host")
    println(s"  Port: $port")
    println(s"  Mode: $mode")

// Run: scala ServerLauncher
// Starting server:
//   Host: localhost
//   Port: 8080
//   Mode: development

// Run: scala ServerLauncher api.example.com 443 production
// Starting server:
//   Host: api.example.com
//   Port: 443
//   Mode: production

Summary


Source                  Method                       Returns
──────────────────────  ───────────────────────────  ──────────────
Program arguments       args: Array[String]          String
Interactive line input  StdIn.readLine()             String
Interactive int input   StdIn.readInt()              Int
Interactive double      StdIn.readDouble()           Double
With prompt             StdIn.readLine("prompt: ")   String
Safe arg access         args.lift(index)             Option[String]

For production CLI tools in Scala, libraries like scopt or decline provide argument parsing with flags, options, help text, and type validation. These are worth exploring once you are comfortable with the basics shown here.

Leave a Comment

Your email address will not be published. Required fields are marked *