IO.readln returns null at end of input (Ctrl+D, or redirected files) — check for it.
The classic way:
varscanner=newScanner(System.in);varn=scanner.nextInt();scanner.nextLine();// consume the rest of the line!vartext=scanner.nextLine();
Warning
nextInt() leaves the newline behind, so the next nextLine() returns empty. Safer: read
whole lines and parse them yourself.
intreadInt(Stringprompt,intmin,intmax){while(true){varinput=IO.readln(prompt);if(input==null)thrownewIllegalStateException("input closed");try{varn=Integer.parseInt(input.strip());if(n<min||n>max){IO.println("out of range");continue;}returnn;}catch(NumberFormatExceptione){IO.println("not a number");}}}
Parsing arguments
voidmain(String[]args){Stringfile=null;varverbose=false;varlimit=10;for(vari=0;i<args.length;i++){switch(args[i]){case"-v","--verbose"->verbose=true;case"-n","--limit"->limit=Integer.parseInt(args[++i]);case"-h","--help"->{help();return;}default->{if(args[i].startsWith("-")){IO.println("unknown option");return;}file=args[i];}}}if(file==null){help();return;}run(file,limit,verbose);}voidhelp(){IO.println("""
usage: java Tool.java [options] <file>
-n, --limit N number of results (default 10)
-v, --verbose verbose output
-h, --help this help
""");}
For anything bigger, use picocli:
@Command(name="count",mixinStandardHelpOptions=true,version="1.0")publicclassCountimplementsRunnable{@Parameters(index="0",description="file to read")privatePathfile;@Option(names={"-n","--limit"})privateintlimit=10;@Overridepublicvoidrun(){…}publicstaticvoidmain(String[]args){System.exit(newCommandLine(newCount()).execute(args));}}