Java Scanner로 입력받기: 문자열, 숫자, 반복 입력과 버퍼 문제

Alchemist·2026년 10월 7일

KT AIVLE

목록 보기
65/130

지금까지 변수에 값을 직접 작성했다면 이제는 사용자가 입력한 데이터를 프로그램에서 받아볼 차례다.

콘솔 기반 Java 프로그램에서는 Scanner를 사용해 입력을 받을 수 있다.

Scanner 시작하기

먼저 클래스를 import한다.

import java.util.Scanner;

그리고 입력을 읽을 Scanner 객체를 만든다.

Scanner scanner = new Scanner(System.in);

간단한 전체 예시는 다음과 같다.

import java.util.Scanner;

public class ConsoleApp {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("이름을 입력하세요: ");
        String name = scanner.nextLine();

        System.out.println("안녕하세요, " + name + "님");
    }
}

문자열 입력

한 줄 전체를 읽을 때는 nextLine()을 사용한다.

String message = scanner.nextLine();

공백이 포함된 문자열도 한 줄 전체를 읽는다.

hello java world

정수 입력

int quantity = scanner.nextInt();

사용자가 숫자가 아닌 값을 입력하면 InputMismatchException이 발생할 수 있다.

입력값을 그대로 신뢰하지 않는 것이 중요하다.

실수 입력

double rate = scanner.nextDouble();

입력 타입과 읽으려는 타입이 맞아야 한다.

입력받은 값으로 계산하기

System.out.print("상품 가격: ");
int price = scanner.nextInt();

System.out.print("수량: ");
int quantity = scanner.nextInt();

int total = price * quantity;
System.out.println("총 금액: " + total);

Scanner 자체보다 중요한 것은 입력 → 변수 저장 → 계산 → 출력이라는 데이터 흐름이다.

반복 입력 만들기

사용자가 종료 명령을 입력하기 전까지 계속 동작하는 프로그램을 만들어보자.

import java.util.Scanner;

public class CommandApp {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.print("명령어 입력(exit 종료): ");
            String command = scanner.nextLine();

            if ("exit".equals(command)) {
                break;
            }

            System.out.println("입력한 명령: " + command);
        }
    }
}

여기서는 while, if, break, String.equals()가 함께 사용된다.

기초 문법은 각각 따로 배우지만 실제 프로그램에서는 이렇게 조합된다.

nextInt() 다음 nextLine() 문제

Scanner를 처음 사용할 때 가장 자주 만나는 문제다.

System.out.print("나이: ");
int age = scanner.nextInt();

System.out.print("자기소개: ");
String intro = scanner.nextLine();

intro 입력을 기다리지 않고 바로 넘어갈 수 있다.

왜 그럴까?

숫자를 입력하고 Enter를 누르면 입력 스트림에는 개행 문자가 남을 수 있다. nextInt()는 숫자만 읽고 개행 문자를 소비하지 않기 때문이다.

해결 방법 중 하나는 숫자를 읽은 뒤 nextLine()을 한 번 호출해 남은 개행을 소비하는 것이다.

int age = scanner.nextInt();
scanner.nextLine();

String intro = scanner.nextLine();

또 다른 방법은 모든 입력을 nextLine()으로 받고 필요한 경우 직접 변환하는 것이다.

String input = scanner.nextLine();
int age = Integer.parseInt(input);

이 방식은 입력 검증 흐름을 통일하기 편하다.

변수 값 교환하기

입력 연습에서 자주 접하는 기본 문제 중 하나가 두 변수의 값을 바꾸는 것이다.

int a = 10;
int b = 20;

int temp = a;
a = b;
b = temp;

중간 값을 보존할 임시 변수 temp가 필요하다.

이 문제는 변수의 값이 대입되는 순간 어떻게 바뀌는지 이해하는 데 도움이 된다.

누적 합계와 평균

여러 값을 입력받아 합계와 평균을 계산할 수도 있다.

int sum = 0;
int count = 3;

for (int i = 0; i < count; i++) {
    int value = scanner.nextInt();
    sum += value;
}

double average = (double) sum / count;
System.out.println("평균: " + average);

여기에는 변수, 반복문, 축약 대입, 형변환이 모두 사용된다.

Scanner는 언제까지 사용할까?

Scanner는 Java 문법과 입력 처리 흐름을 연습하기 좋다.

실제 웹 애플리케이션에서는 사용자의 입력이 HTTP 요청, JSON, 폼 데이터 등의 형태로 들어오는 경우가 많다. 하지만 콘솔 입력으로 익힌 입력을 받고 → 검증하고 → 처리하고 → 결과를 만드는 흐름은 그대로 이어진다.

Scanner 객체는 한 번 만들고 재사용하기

간단한 콘솔 프로그램에서는 입력할 때마다 Scanner를 새로 만들 필요가 없다.

Scanner scanner = new Scanner(System.in);

int first = scanner.nextInt();
int second = scanner.nextInt();
String line = scanner.nextLine();

하나의 입력 스트림 System.in을 같은 Scanner로 계속 읽는 방식이 자연스럽다.

입력 메서드와 기대 타입을 맞춘다

int quantity = scanner.nextInt();
double rate = scanner.nextDouble();
String name = scanner.nextLine();

각 메서드는 기대하는 입력 형식이 다르다. 예를 들어 nextInt()가 숫자를 기다리는데 hello를 입력하면 InputMismatchException이 발생할 수 있다.

초보 실습에서는 "정상 입력만 들어온다"고 가정해도 되지만 실제 애플리케이션에서는 사용자 입력 검증과 예외 처리가 필요하다.

종료 값을 이용하는 sentinel 패턴

입력 프로그램에서 특정 값을 종료 신호로 정하는 방식이 자주 나온다.

int sum = 0;

while (true) {
    System.out.print("숫자 입력(0 종료): ");
    int number = scanner.nextInt();

    if (number == 0) {
        break;
    }

    sum += number;
}

System.out.println("합계=" + sum);

여기서 0은 일반 데이터가 아니라 반복을 끝내는 sentinel value 역할을 한다.

문자열에서도 같은 방식으로 만들 수 있다.

if ("exit".equals(command)) {
    break;
}

두 입력값이 모두 특정 값일 때 종료하기

여러 조건을 함께 사용할 수도 있다.

while (true) {
    int x = scanner.nextInt();
    int y = scanner.nextInt();

    if (x == 0 && y == 0) {
        break;
    }

    System.out.println("합=" + (x + y));
}

&&는 두 조건이 모두 참이어야 하므로 (0, 0) 입력일 때만 종료한다.

nextInt()와 nextLine()을 섞을 때 실제 흐름

사용자가 다음처럼 입력한다고 생각해보자.

20[Enter]

입력 스트림에는 개념적으로 숫자 20 뒤에 줄바꿈 정보가 함께 있다. nextInt()는 정수 토큰만 소비하고 줄 끝은 다음 입력 처리에 남을 수 있다.

int age = scanner.nextInt();
scanner.nextLine(); // 남은 줄 끝 소비
String name = scanner.nextLine();

이 한 줄을 왜 넣는지 원리를 알고 사용하는 것이 중요하다.

모든 입력을 문자열로 통일하는 방법

조금 더 일관된 입력 흐름을 원하면 한 줄 단위로 받고 직접 변환할 수도 있다.

System.out.print("수량: ");
String rawQuantity = scanner.nextLine();
int quantity = Integer.parseInt(rawQuantity);

장점은 문자열 입력과 숫자 입력의 경계를 통일할 수 있다는 것이다. 대신 숫자로 변환할 수 없는 값에 대한 NumberFormatException 처리를 고민해야 한다.

메뉴 프로그램으로 기초 문법 연결하기

int totalAmount = 0;

while (true) {
    System.out.println("1. 상품 추가");
    System.out.println("2. 결제");
    System.out.println("3. 종료");

    int menu = scanner.nextInt();
    scanner.nextLine();

    if (menu == 1) {
        System.out.print("상품명: ");
        String productName = scanner.nextLine();

        System.out.print("가격: ");
        int price = scanner.nextInt();
        scanner.nextLine();

        totalAmount += price;
        System.out.println(productName + " 추가 완료");
    } else if (menu == 2) {
        System.out.println("결제 금액=" + totalAmount);
        totalAmount = 0;
    } else if (menu == 3) {
        break;
    }
}

이 정도 프로그램만 만들어도 Scanner, 변수, 조건문, 반복문, break, 누적 합계를 한 번에 연습할 수 있다.

입력 문제를 풀 때 보는 순서

입력 프로그램이 꼬이면 다음 순서로 확인한다.

  1. 어떤 메서드로 입력을 읽었는가?
  2. 현재 입력 버퍼에 무엇이 남아 있을 수 있는가?
  3. 읽어온 값의 타입은 무엇인가?
  4. 종료 조건이 입력보다 먼저/나중 어느 시점에 검사되는가?
  5. 누적 변수나 카운터를 올리는 위치가 맞는가?

특히 nextInt()와 nextLine()을 번갈아 쓸 때는 1~2번을 먼저 확인하면 원인을 빠르게 찾을 수 있다.

핵심 정리

  • Scanner는 콘솔 입력을 읽을 때 사용할 수 있다.
  • nextLine()은 문자열 한 줄을 읽는다.
  • nextInt(), nextDouble()은 각각 정수와 실수를 읽는다.
  • 입력 타입이 맞지 않으면 예외가 발생할 수 있다.
  • while (true)와 break를 조합하면 종료 명령을 받을 때까지 반복할 수 있다.
  • nextInt() 후 nextLine()을 사용하면 남은 개행 문자 때문에 입력이 건너뛰어질 수 있다.
  • 여러 입력을 처리하면서 변수, 조건문, 반복문, 형변환을 함께 연습할 수 있다.
profile
html_programming_language

0개의 댓글