System.in이란?
먼저 System.in은 java.io.*에서 Import하는 클래스입니다
System.in 값을 입력받는 클래스로 보시면 됩니다
값은 여러가지 방식으로 들어오기 때문에 만약 잘못된 값이 들어온 경우 에러가 나지 않도록 예외처리를 필수로 해줘야합니다
try-catch구문 혹은 IOException을 사용하여 예외처리를 하지 않으면 에러가 나타납니다
이제 예제를 통해서 System.in의 사용법에 대해서 알아보겠습니다
System.in.read()
System.in.read() 에 대해서 설명하겠습니다
read() 메서드는 한 바이트씩 입력된 값을 읽어드리는 메서드입니다
한 바이트씩 입력을 받기 때문에 한글은 입력받지 못 합니다
영어, 숫자, 특수문자 등을 입력받을 수 있습니다
아래 코드는 System.in.read()에 대한 예제입니다
1. System.in.read()에 48을 빼서 숫자를 출력합니다
System.in.read()는 아스키코드로 값을 받기때문에 48을 빼서 숫자정수로 받을 수 있습니다
// System.in.read()는 기본적으로 아스키코드로 값을 받습니다 -> Int형으로 받음
// 아스키코드에서 48을 빼면 숫자랑 같아져서 -48을 하여 숫자로 받을 수 있습니다
int Number = System.in.read() - 48;
2. System.in.read() -> char형으로 변환 문자열을 출력합니다
아스키코드는 char형으로 변환하면 문자열로 표시가 됩니다
그것을 응용하여 문자열이 출력되도록 합니다
// System.in.read()는 기본적으로 아스키코드로 값을 받습니다 -> Int형으로 받음
// 아스키코드에서 Char형으로 변경하면 문자열로 입력을 받을 수 있습니다
char Char = (char) System.in.read();
3. System.in.read(바이트, StartByte, EndByte)
System.in.read 다른 메서드입니다
바이트배열로 받는 방법입니다
바이트배열을 값을 받아서 String으로 변환합니다
String변환하면 나머지 배열의 값에서 공백부분이 쓰레기데이터가 남으므로 trim()을 사용하여 쓰레기데이터를 정리해줍니다
// System.in.read(바이트배열, StartByte, EndByte) -> 바이트배열로 입력받은 값을 집어넣습니다
// Byte배열 변수 선언
byte[] Byte = new byte[4096];
// Byte배열에 값을 입력
System.in.read(Byte, 0, 4096);
// Byte -> String전환
String StrByte = new String(Byte);
// 전환 시 Byte배열의 쓰레기데이터를 trim으로 정리
StrByte = StrByte.trim();
여기까지 System.in.read()의 세 가지 예제에 대해서 간단하게 알아봤습니다
아래에는 전체 코드와 결과 화면입니다
전체 코드
import java.io.IOException;
public class SystemIn {
public static void main(String[] args) throws IOException {
// System.in.read()는 기본적으로 아스키코드로 값을 받습니다 -> Int형으로 받음
// 아스키코드에서 48을 빼면 숫자랑 같아져서 -48을 하여 숫자로 받을 수 있습니다
int Number = System.in.read() - 48;
// 아스키코드에서 Char형으로 변경하면 문자열로 입력을 받을 수 있습니다
char Char = (char) System.in.read();
// Number 및 Char 결과 출력
System.out.println("Number : " + Number);
System.out.println("Char : " + Char);
// System.in.read(바이트배열, StartByte, EndByte) -> 바이트배열로 입력받은 값을 집어넣습니다
// Byte배열 변수 선언
byte[] Byte = new byte[4096];
// Byte배열에 값을 입력
System.in.read(Byte, 0, 4096);
// Byte -> String전환
String StrByte = new String(Byte);
// 전환 시 Byte배열의 쓰레기데이터를 trim으로 정리
StrByte = StrByte.trim();
// StrByte 결과 출력
System.out.print("StrByte : " + StrByte);
}
}
결과 화면

new Scanner(System.in);
자바를 시작한지 얼마 안되면 아무것도 모른채 외우는 구문입니다
Scanner 클래스를 사용하여 값을 입력받는 메서드입니다
System.in을 사용하여 Scanner의 다양한 메서드를 사용 다양한 값을 입력받습니다
예제를 통해서 알아보겠습니다
1. sc.next();
sc.next()는 공백을 입력하기 전까지의 값을 입력받는 Scanner의 메서드입니다
// next()를 사용하여 Space를 치기 전까지의 값을 입력합니다
String str1 = sc.next();
2. sc.nextLine();
sc.nextLine()은 Enter를 입력하기 전까지의 값을 입력받는 Scanner의 메서드입니다
// nextLine()을 사용하여 Enter를 치기 전까지의 값을 입력합니다
String str2 = sc.nextLine();
3. sc.nextInt();
sc.nextInt()는 Enter를 입력하기 전까지의 정수값을 입력받는 Scanner의 메서드입니다
정수값만 입력받으므로 문자열이 들어가는 경우 에러가 뜹니다
// nextInt()를 사용하면 Enter를 치기 전까지의 숫자값을 입력합니다
// nextInt()는 숫자만 입력받을 수 있으므로 문자열이 들어가면 에러가 뜹니다
int ScannInt = sc.nextInt();
Scanner의 사용방법은 더 있지만 제일 많이 사용하는 세 가지 방법에 대해서 알아봤습니다
아래는 전체코드와 결과 화면입니다
참고바랍니다!!
전체 코드
import java.io.IOException;
import java.util.Scanner;
public class SystemIn {
public static void main(String[] args) throws IOException {
// 자바를 시작하면 기본적으로 외우게되는 Scanner에서 사용하는 System.in입니다
// Scanner를 사용하여 값을 입력받습니다
Scanner sc = new Scanner(System.in);
// next()를 사용하여 Space를 치기 전까지의 값을 입력합니다
String str1 = sc.next();
// nextLine()을 사용하여 Enter를 치기 전까지의 값을 입력합니다
String str2 = sc.nextLine();
// nextInt()를 사용하면 Enter를 치기 전까지의 숫자값을 입력합니다
// nextInt()는 숫자만 입력받을 수 있으므로 문자열이 들어가면 에러가 뜹니다
int ScannInt = sc.nextInt();
// 결과출력
System.out.println("str1 : " + str1);
System.out.println("str2 : " + str2);
System.out.println("ScannInt : " + ScannInt);
}
}
결과 화면
결과화면을 보시면
첫 번째는 sc.next()를 썼기때문에 첫번째 str1은 "ABCDE"까지만 출력이 됩니다
두 번째는 sc.nextLine()을 써서 str2는 "FGHIJKLMNOPQRSTUVWXYZ"까지 출력이 됩니다
마지막으로 sc.nextInt()를 써서 "1234567890"이 출력이 됩니다

new BufferedReader(new InputStreamReader(System.in));
이것도 마찬가지로 자바를 하는 분들이라면 외우는 구문입니다
BufferedReader를 사용하여 바로바로 System.in으로 넣은 값을 읽어드리는 방법입니다
예제를 통해서 사용 방법에 대해서 알아보겠습니다!
1. br.readLine():
br.readLine()을 사용하여 Enter를 치기 전까지의 값을 읽어드립니다
// readLine()을 사용하여 Enter키를 입력하기 전까지의 값을 입력받는다
String brStr = br.readLine();
2. Integer.parseInt(br.readLine());
Integer.parseInt(br.readLine())을 사용하여 Enter를 치기 전까지의 값을 읽어드립니다
BufferedReader에서는 Int로 값을 읽는 방법이 없습니다
숫자를 입력받기 위해서는 Integer.parseInt를 사용하여 String을 Int로 변환해야합니다
// BufferedReader는 String변수만 받으므로 숫자로 변환하려면
// Integer.parseInt를 사용하여 String을 Int로 변환해야합니다
int brInt = Integer.parseInt(br.readLine());
전체 코드와 결과 화면을 알아보겠습니다
전체 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class SystemIn {
public static void main(String[] args) throws IOException {
// BufferedReader 변수 선언
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// readLine()을 사용하여 Enter키를 입력하기 전까지의 값을 입력받는다
String brStr = br.readLine();
// BufferedReader는 String변수만 받으므로 숫자로 변환하려면
// Integer.parseInt를 사용하여 String을 Int로 변환해야합니다
int brInt = Integer.parseInt(br.readLine());
// 결과 출력
System.out.println("brStr : " + brStr);
System.out.println("brInt : " + brInt);
}
}
결과 화면
결과 화면을 보시면
A - Z까지 출력된 후
1- 0까지 출력이 됩니다

추가설명 :
ChatGpt에 물어본 Scanner.nextLine() 및 BufferedReader에 대하여.
Scanner.nextLine() 메서드에 대한 주석을 쉽게 풀어서 설명드릴게요.
Scanner.nextLine() 메서드는 현재 줄을 읽고 다음 줄로 이동하는 기능을 합니다. 구체적으로는 다음과 같은 방식으로 작동합니다:
- 현재 줄의 나머지 내용을 모두 읽고 반환합니다. 만약 중간에 읽다가 남은 내용이 있더라도, 메서드를 호출하면 그 줄의 나머지 텍스트를 반환합니다.
- 줄 구분자(line separator)는 포함되지 않습니다. 예를 들어, 줄 끝에 줄바꿈 문자(엔터)가 포함되어 있을 경우, 그 부분은 제외하고 텍스트만 반환합니다.
- 다음 줄의 시작으로 위치를 옮깁니다. 이 메서드를 호출하고 나면, 스캐너의 위치가 다음 줄의 첫 부분으로 설정됩니다. 그래서 다시 nextLine()을 호출하면 그다음 줄을 읽을 준비가 됩니다.
- 줄 구분자가 없으면 모든 입력을 버퍼링합니다. 만약 입력 전체에 줄바꿈 문자가 없다면(즉, 한 줄로 쭉 연결된 입력만 있다면), nextLine()은 줄 구분자를 찾을 때까지 입력을 계속 읽습니다.
나의 말:
버퍼링 한다는게 기다린다는 뜻이야? 그래서 BufferedReader 같은 클래스와 함께 쓰는건가? 나는 사실 아직도 BufferedReader와 같이 Buffer가 들어가는 클래스나 함수에 대해서 정확히 이해하지 못했는데. 너가 자세히 설명해줄수 있어?
ChatGPT의 말:
좋은 질문이에요! 자바에서 "버퍼링(buffering)"과 "버퍼(buffer)"라는 개념은 성능과 데이터 입출력을 효율적으로 관리하기 위해 사용하는 기술입니다. Scanner나 BufferedReader 같은 클래스가 왜 버퍼링을 사용하는지, 그리고 이 개념이 어떻게 작동하는지 차근차근 설명해볼게요.
1. 버퍼(Buffer)란 무엇인가?
- 버퍼는 데이터를 임시로 저장해 두는 메모리 공간입니다. 이 공간을 사용하면 한 번에 읽거나 쓰는 데이터의 양을 줄이고, 불필요하게 장치를 반복해서 접근하지 않아도 됩니다.
- 예를 들어, 파일을 한 번에 모든 내용을 읽어야 하는 경우보다, 조금씩 나눠서 여러 번 읽는 것이 더 효율적일 때 버퍼를 사용합니다. 이렇게 하면 프로그램이 필요한 만큼만 읽어가며 메모리 사용량을 조절할 수 있습니다.
2. 버퍼링(Buffering)이란?
- 버퍼링은 데이터를 한 번에 처리하지 않고, 일정량 모아서 처리하는 방식입니다.
- 예를 들어, 키보드 입력을 받을 때마다 바로 처리하지 않고, 여러 입력을 모아서 한 번에 처리하면 성능이 더 효율적일 수 있습니다. 네트워크 통신에서도, 패킷을 한 번에 여러 개 받아서 처리하면 응답이 빨라지는 것과 비슷한 원리입니다.
3. BufferedReader와 Scanner의 차이
- BufferedReader: 파일이나 네트워크와 같은 입력 스트림에서 데이터를 읽을 때 사용하며, 버퍼링을 통해 성능을 높입니다. 기본적으로 큰 덩어리로 데이터를 읽어서 처리 속도를 개선하죠.
- Scanner: BufferedReader와 다르게 형식화된 텍스트(숫자, 단어 등)를 분석하기 쉽게 제공하는 클래스입니다. nextLine() 같은 메서드는 라인 단위로 처리하기 때문에, 라인이 끝날 때까지 데이터를 읽으면서 줄바꿈을 기준으로 나눠서 반환합니다.
BufferedReader는 줄 단위로 읽는 readLine() 메서드를 제공하고, Scanner는 각 라인이나 단어별로 쉽게 접근할 수 있는 기능을 제공하는 것이 차이입니다.
4. 버퍼링의 장점
- 데이터를 매번 읽지 않고, 버퍼에 일정량을 미리 읽어 두기 때문에 디스크나 네트워크 접근이 줄어들어 성능이 좋아집니다.
- CPU와 메모리의 부하를 줄이고, 처리 시간을 단축시킬 수 있습니다.
5. BufferedReader와 함께 쓰는 이유
- BufferedReader는 더 큰 블록으로 읽기 때문에, Scanner와 함께 사용하면 파일이나 큰 데이터 스트림을 효율적으로 처리할 수 있습니다. Scanner는 데이터를 분석하기 쉽지만 자체적인 버퍼링이 약한 편이기 때문에, BufferedReader와 함께 쓰면 데이터 읽기 성능을 높일 수 있습니다.
결론적으로 Scanner의 nextLine()이 줄을 찾을 때까지 "기다린다"는 건, 입력이 완료되거나 줄 구분자가 나타날 때까지 데이터를 버퍼에 쌓아두고 계속 읽는 것을 의미해요. 이를 통해 데이터를 끊김 없이 처리할 수 있게 됩니다.
StreamTokenizer와 StringTokenizer의 차이점에 대해 자세히 알려줄래? 어떨때 어떻게 쓰는건지도 알려줘
ChatGPT의 말:
StreamTokenizer와 StringTokenizer는 둘 다 문자열을 특정 기준으로 나누어주는 기능을 제공하지만, 사용 목적과 방식에 차이가 있습니다. 두 클래스를 비교하고, 각각 어떤 상황에서 유용한지 설명해볼게요.
1. StreamTokenizer
- 용도: StreamTokenizer는 주로 텍스트 파일이나 문자열 스트림을 읽어서, 하나씩 토큰을 구분하며 처리할 때 사용됩니다. 파일에서 단어, 숫자, 기호 등 다양한 요소를 한 번에 다루어야 할 때 유용합니다.
- 특징:
- 토큰 단위: 텍스트를 읽으면서 숫자, 단어, 기호를 구분해주며, 이러한 **구분된 단위(토큰)**를 반환합니다.
- 문법적 구분: 주석, 공백, 숫자와 같은 요소들을 다르게 구분할 수 있으며, C 언어 스타일의 주석(//와 /* */)을 자동으로 무시하는 기능도 있습니다.
- 입력 스트림을 기반으로 작동: StreamTokenizer는 Reader 클래스를 기반으로 동작하여, 파일이나 기타 입력 스트림에서 읽은 텍스트를 토큰 단위로 나누는 데 유용합니다.
- 주요 메서드 및 필드:
- nextToken(): 다음 토큰을 읽고, 어떤 종류의 토큰인지 구분합니다. (예: TT_WORD는 단어, TT_NUMBER는 숫자, TT_EOF는 파일 끝 등을 나타냄)
- sval, nval: 읽은 토큰이 단어면 sval 필드에, 숫자면 nval 필드에 저장됩니다.
- 사용 예시:
- 문서 분석: 텍스트 파일의 내용에서 단어와 숫자를 구분하여 읽어야 할 때.
- 구조화된 텍스트 처리: 구성 요소가 단어와 숫자로 이루어진 데이터를 다루는 경우 (예: 텍스트 기반 설정 파일).
2. StringTokenizer
- 용도: StringTokenizer는 문자열을 특정 구분자(delimiter)를 기준으로 나눌 때 사용됩니다. 구분자가 있는 한 줄의 텍스트에서 각각의 단어를 빠르게 분리해야 하는 상황에서 유용합니다.
- 특징:
- 간단한 구분 기능: 단순히 문자열을 구분자로 나누는 데 집중하며, 구분자를 여러 개 지정할 수 있습니다.
- 정규 표현식 미지원: StringTokenizer는 정규식을 지원하지 않기 때문에, 복잡한 패턴이나 여러 종류의 구분자를 유연하게 다루기엔 제한적입니다.
- 문자열 기반: 입력이 문자열일 때 최적화되어 있으며, 파일이나 입력 스트림을 다루는 경우에는 추가 변환이 필요합니다.
- 주요 메서드:
- hasMoreTokens(): 더 이상 구분된 단어가 없을 때까지 토큰을 계속 가져올 수 있는지 확인합니다.
- nextToken(): 다음 토큰을 반환합니다.
- 사용 예시:
- 단순 데이터 분리: CSV 같은 단순한 형식의 문자열을 구분자 하나로 나누어 처리해야 할 때.
- 빠른 문자열 처리: 성능이 중요한 상황에서 단순히 구분자로 문자열을 나눌 때 유용합니다.
3. 차이점 요약
특징StreamTokenizerStringTokenizer입력 소스 | Reader 기반 (파일, 스트림 등) | String 기반 |
토큰 구분 | 단어, 숫자, 기호, 공백 등 자동 인식 | 지정된 구분자 기반으로 토큰 분리 |
구분자 설정 | 특정 문자나 주석 처리 가능 | 단일 문자열 구분자 설정 |
주 용도 | 파일 또는 스트림에서 텍스트를 토큰 단위로 분석 | 문자열에서 간단히 데이터 분리 |
4. 어떤 상황에서 어떤 것을 쓸지
- StreamTokenizer는 텍스트 파일을 읽으며 단어와 숫자를 동시에 다루고 싶을 때 유용합니다. 파일의 구성을 분석하거나 파일의 데이터를 구조화하여 처리해야 할 경우 좋습니다.
- StringTokenizer는 간단히 문자열을 나누기만 하면 될 때 사용됩니다. 한 줄에서 특정 구분자 기준으로 데이터만 분리하고 싶을 때 간편하게 사용할 수 있습니다.
StreamTokenizer는 다소 복잡하지만 파일을 포함한 다양한 입력 스트림에서 다채로운 구분을 지원하는 반면, StringTokenizer는 가볍고 빠르게 특정 구분자로만 문자열을 나누는 데 최적화된 도구입니다.
StringTokenize.nextToken() 과 BufferedReader.readLine()에 대해 설명해줘.
우선 내가 이해하고 있는게 맞는지 봐줘. BufferedReader.readLine()의 경우 전체 문장에서 엔터(\n)로 끝나는 부분까지 한 라인을 통채로 읽어오는거고, StringTokenize.nextToken() 의 경우, 위에서 읽어온 한라인을 하나씩 띄워쓰기(?) 기준으로 한 글자씩 읽어서 리턴해주는거니?
네, 큰 흐름은 잘 이해하고 계신 것 같아요! 그런데 StringTokenizer의 nextToken()은 띄어쓰기 기준이 아니라, 지정한 구분자 기준으로 나누어진 토큰(단어나 구) 하나씩을 반환하는 방식입니다. 더 구체적으로 설명드릴게요.
1. BufferedReader.readLine()
- 작동 방식: BufferedReader.readLine() 메서드는 전체 문장에서 한 줄(line)을 읽어오는 기능을 합니다.
- 읽기 범위:
- 한 줄 끝까지, 즉 줄바꿈 문자(\n 또는 \r\n)가 나올 때까지 모든 문자를 읽어서 문자열로 반환합니다.
- 이 메서드는 줄바꿈 문자를 포함하지 않으며, 다음 호출 시 다음 줄부터 읽기 시작합니다.
- 주로 사용하는 상황:
- 텍스트 파일에서 한 줄씩 데이터를 읽고 싶을 때 사용합니다. 예를 들어, CSV 파일이나 설정 파일 등 줄 단위로 구성된 데이터를 처리할 때 유용합니다.
예시:
2. StringTokenizer.nextToken()
- 작동 방식: StringTokenizer.nextToken() 메서드는 지정한 구분자(기본적으로 공백)를 기준으로 문자열을 나누어, 나누어진 각 조각(토큰)을 하나씩 반환합니다.
- 구분자 설정:
- 기본 구분자는 공백 문자(스페이스, 탭 등)입니다.
- 구분자를 원하는 문자로 지정할 수도 있으며, 여러 구분자도 사용할 수 있습니다. 예를 들어, 쉼표나 세미콜론 등으로 구분된 데이터를 나눌 수 있습니다.
- 읽기 범위:
- 지정된 구분자가 나올 때마다 나누어진 각 단어(토큰)를 개별적으로 반환합니다.
- nextToken()을 호출할 때마다 문자열을 하나씩 가져오며, 더 이상 구분된 문자열이 없으면 종료됩니다.
- 주로 사용하는 상황:
- 한 줄의 텍스트에서 구분자를 기준으로 단어별로 나누어 처리하고 싶을 때 사용합니다. 예를 들어, 쉼표로 구분된 데이터나 공백으로 구분된 단어들을 읽고 싶을 때 유용합니다.
예시:
정리하자면:
- **BufferedReader.readLine()**은 파일에서 한 줄 전체를 읽어오는 것입니다. 줄바꿈을 기준으로 각 라인을 읽으며, 여러 줄을 처리할 때 파일의 각 줄을 통째로 가져오는 방식으로 적합합니다.
- **StringTokenizer.nextToken()**은 한 줄을 특정 구분자로 나누어 각 단어(또는 토큰)를 하나씩 반환하는 것입니다. 한 줄을 읽은 다음에 특정 기준으로 나누어야 할 때 사용합니다.
BufferedReader.readLine()으로 전체 라인을 읽은 뒤, StringTokenizer로 구분자를 기준으로 그 줄을 세부적으로 나누어 사용하는 방식이 일반적입니다.
참고링크1 : https://crazykim2.tistory.com/535
참고링크2 : https://whitewing4139.tistory.com/219
[Java Basic] 11. 입력값 받기 - System.in과 Scanner 클래스
지금까지 Java의 기본적인 내용을 포스팅하면서, 변수를 생성하고 출력하는 부분에 대해서만 예시로 많이 보여주었는데, 사용자를 위해 개발되는 프로그램을 떠올려보면 사용자로부터 값을 입
whitewing4139.tistory.com
'Java' 카테고리의 다른 글
[Java] Int와 Long 사용 구분하기 (2) | 2024.12.02 |
---|---|
[Java] Scanner vs BufferedReader (0) | 2024.11.25 |
Java소스 Class파일 디컴파일 (5) | 2024.10.03 |
JAVA 기본 (1) | 2024.10.03 |
[Java] Lambda 식, 문자열포함, Stream.reduce (2) | 2024.05.07 |