JAVA / GETTING STARTED
Printing, formatting output and reading console input
Print with print, println and printf, control width and rounding with format specifiers, and read typed lines and numbers using Scanner.
What you will learn
- Pick print for prompts, println for whole lines, printf for formatted values
- Match each specifier to its argument type: %d, %f, %s, plus width and precision
- Read typed input with a Scanner over System.in: nextLine, nextInt, nextDouble
- Clear the leftover newline when a nextLine call follows nextInt
Understanding Printing, formatting output and reading console input
System.out is a PrintStream object held in a static field of System, so every printing call is a method call on that one object. print writes exactly the characters of its argument and stops there; println writes them and then the platform line separator; printf writes them after running a format string through java.util.Formatter. Because print leaves the cursor where it stopped, a prompt that should sit on the same line as the answer must use print, while a line that stands on its own uses println.
A format string is a template that is scanned left to right, and each % specifier pulls the next argument in order and converts it: %d for integral types, %f for floating point, %s for anything at all through its toString. What sits between the % and the conversion letter is a display instruction only, so %8.2f right-aligns the number in eight columns and rounds it to two decimals for printing while the double in memory is untouched, and a minus sign as in %-8s flips the padding to the other side. Prefer %n over \n for line breaks: %n emits whatever separator the current platform uses, whereas \n always emits a single line-feed character.
Input is the same stream idea in reverse. System.in is a raw byte stream that knows nothing about numbers or lines, so you wrap it: new Scanner(System.in) adds a layer that splits the incoming characters into whitespace-separated tokens and converts them on request. Each next method blocks until the terminal hands over a line, which only happens when Enter is pressed, and then consumes just the characters it needs. That last detail is the whole reason nextInt leaves the newline behind for a following nextLine to find.
public class Receipt {
public static void main(String[] args) {
String item = "espresso";
int quantity = 3;
double unitPrice = 2.5;
double total = quantity * unitPrice;
System.out.print("Order: ");
System.out.print(quantity);
System.out.println(" x " + item);
System.out.printf("Unit price: %6.2f%n", unitPrice);
System.out.printf("%-10s %3d %8.2f%n", item, quantity, total);
System.out.printf("Total is %.1f for %d items%n", total, quantity);
}
}Output and input are two directions on one character stream: each print call writes exactly the characters you asked for, and each Scanner call consumes exactly the input it needs and no more.
Worked examples
Prompting and reading with Scanner
Shows a prompt written with print and two answers read from the keyboard with nextLine and nextInt.
import java.util.Scanner;
public class Greeter {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Name: ");
String name = in.nextLine();
System.out.print("Year of birth: ");
int year = in.nextInt();
System.out.printf("%s will be %d at the end of 2026.%n", name, 2026 - year);
in.close();
}
}Example explained
Line 1new Scanner(System.in) wraps the raw byte stream from the keyboard in an object that can hand back lines and numbers.
Line 2print rather than println keeps the cursor after "Name: ", so the typed answer appears on the same line as the prompt.
Line 3nextLine() returns everything up to the Enter key without the newline itself, so a name containing spaces survives intact.
Line 4In the transcript, Ada and 1990 are typed by the user; the program writes only the two prompts and the final line.
Why nextLine after nextInt looks skipped
Reproduces the leftover-newline problem deterministically by giving Scanner a String instead of the keyboard.
import java.util.Scanner;
public class TokenTrap {
public static void main(String[] args) {
Scanner in = new Scanner("42\nDouglas Adams\n");
int number = in.nextInt();
String stray = in.nextLine();
String title = in.nextLine();
System.out.println("number = " + number);
System.out.println("stray = [" + stray + "]");
System.out.println("title = [" + title + "]");
}
}Example explained
Line 1A Scanner can read from a String exactly as it reads from System.in, so the trap is reproducible without typing anything.
Line 2nextInt() consumes the characters 4 and 2 and stops; the newline after them is still unread.
Line 3The first nextLine() therefore returns the empty remainder of that same line, printed here as [].
Line 4Fix it by calling nextLine() once to discard the leftover, or by reading every line with nextLine() and converting with Integer.parseInt.
Aligned columns with String.format
Uses width specifiers to build a table where text is left-aligned and numbers are right-aligned.
public class Table {
public static void main(String[] args) {
String[] names = {"Ada", "Grace", "Barbara"};
int[] scores = {7, 128, 42};
System.out.printf("%-8s|%5s%n", "NAME", "SCORE");
System.out.println("--------+-----");
for (int i = 0; i < names.length; i++) {
String row = String.format("%-8s|%5d", names[i], scores[i]);
System.out.println(row);
}
System.out.printf("%-8s|%5d%n", "TOTAL", 7 + 128 + 42);
}
}Example explained
Line 1String.format takes the same format string as printf but returns the text instead of writing it, so a row can be built now and printed later.
Line 2%-8s pads names on the right while %5d pads numbers on the left, which is why the digits line up on their last column.
Line 3These format strings end without %n because println supplies the line break itself.
Line 4%5s and %5d use the same width, so the header sits directly above the numbers.
print, println and a nested formatted value
Shows how consecutive print calls build one line and how printf can be chained onto the same line before a println closes it.
public class OneLine {
public static void main(String[] args) {
double ratio = 2.0 / 3.0;
System.out.print("ratio");
System.out.print(" = ");
System.out.printf("%.3f", ratio);
System.out.println(" (rounded for display)");
System.out.println(ratio);
}
}Example explained
Line 1Three print/printf calls write into the same line because none of them emits a line terminator.
Line 2%.3f rounds only the printed text; the double still holds the full value, as the last line proves.
Line 3println(double) uses the value's own text form, which is why the two lines disagree.
Important notes
printf and String.format use the default locale, so on a machine configured for German %.2f prints 7,50 instead of 7.50; pass Locale.US as the first argument when the separator must be fixed.
nextInt() throws InputMismatchException when the next token is not a number and leaves that token unread, so a retry loop that does not consume the bad token with next() will spin forever.
Common mistakes
Using %d for a double or %f for an int: this compiles fine and then throws IllegalFormatConversionException at runtime, for example "d != java.lang.Double" for printf("%d%n", 2.5).
Calling nextLine() immediately after nextInt(): it returns the empty rest of the number's line, so the next prompt appears to be skipped and the string ends up blank.
Writing System.out.println("Total: " + 2 + 3) and expecting 5: + evaluates left to right and becomes string concatenation once one side is a String, so it prints Total: 23 unless the arithmetic is parenthesised.
Try it yourself
Change, predict, then run
Write a program that reads a product name with nextLine, a quantity with nextInt and a unit price with nextDouble, then prints one line such as 4 x bolt @ 0.75 = 3.00 using a single printf with %d, %s and %.2f. If your editor has no input box, feed the same three values to a Scanner built over the string "bolt\n4\n0.75\n".
Open the Java workspaceCheck your understanding
A program prints "Age: ", calls in.nextInt(), prints "City: ", calls in.nextLine() into city, then prints [city]. The user types 30, Enter, Oslo, Enter. What happens?
- It prints [Oslo], because nextLine() skips the leftover newline before reading text.
- It throws InputMismatchException, because nextLine() cannot be called after nextInt().
- It prints [] without waiting, because nextLine() returns the empty remainder of the line the number was on.
- It prints [30], because nextLine() re-reads the whole line that nextInt() already consumed.
Show answer
nextInt() stops right after the last digit of 30 and leaves the newline from Enter unread, so nextLine() reads up to that newline and returns the empty string between them; the program never blocks and Oslo is still sitting unread in the buffer. Option 0 is tempting because the token-based methods (next, nextInt, nextDouble) really do skip leading whitespace, but nextLine() is not token-based: it returns everything up to the next line break, even when that is nothing.