2장 - 입출력 다루기

2025. 2. 11. 10:52·Language/Java Language

Intro

프로그래밍에서 기본은 입력과 출력이다.

입력(input)은 명령에 필요한 데이터를 입력하는 것이고, 출력(output)은 입력받은 데이터로 명령을 수행한 결과를 보여주는 것이다.

보통 둘을 합쳐 입출력(I/O)라고 하며, 일반적으 마우스나 키보드 등의 입력장치로 데이터를 입력 받아 모니터 화면에 출력한다.


2.1. 출력하기

자바에서 출력을 수행하는 대표적인 명령어는 다음과 같다.

  • print()
  • printf()
  • println()

출력 명령을 내릴 때는 다음과 같은 형태로 명령문을 작성해야한다.

System.out.print("Hello");
System.out.printf("Hello");
System.out.println("Hello");

 

 

자바는 일반 프로그램과 달리 JVM 위에서 실행된다. 따라서 프로그램이 직접 운영체제에 접근할 수가 없다.

자바 프로그램에서 운영체제의 기능(키보드 입력, 프로그램 종료 등)을 사용하려면 연결고리가 필요하며, System 클래스가 이 연결고리 역할을 담당한다. 

-> 그래서 출력 명령어 앞에 System 클래스를 연결해 사용한다.

 

 

 

2.1.1. println() 사용 배경

public class Main{
    public static void main(String[] args){
        System.out.print("Hello");
        System.out.print("Java");
    }
}

 

print()는 명령어 내용을 출력한 뒤 줄을 바꾸지 않는다. 즉 코드는 두 개의 print()를 두 줄에 걸쳐 쓰고있지만, 출력될때는 줄 바꿈되지 않고 한 줄에 이어져 써진다.

 

줄 바꿈을 하여 다음 줄에 문자열을 출력하고 싶다면 특수문자(개행문자) \n을 사용하면 된다.

개행문자는 문자열 내에 그냥 문자처럼 쓰면 된다(특수"문자"니깐!!)

public class Main{
    public static void main(String[] args){
        System.out.print("Hello\n");
        System.out.print("Java");
    }
}

 

 

 

 

2.1.2. 특수문자

자바에는 특수한 역할을 하는 문자들이 있고, 특수 문자임을 나타내기 위해 \를 붙인다. 

백슬래시는 뒤에 다른 문자가 오면 문자의 의미를 확장시키기 때문에 이스케이프 문자(escape character)라고도 불린다.

자주 쓰이는 특수문자는 아래와 같다. \b와 \r은 잘 이해가 되지 않아 아래 코드에 남겨봤다.

특수 문자  
\b 커서를 한 문자 앞으로(백스페이스=앞의 문자를 하나 지움)
\r 줄의 맨 앞으로(캐리지 리턴)
\n 줄 바꿈
\t 탭, 들여쓰기
\0 빈칸(null)
System.out.print("Hel\blo");
//HeloJava

System.out.print("Hel\rlo");
//loJava

 

 

 

2.1.3. println()으로 줄 바꿔 출력하기★

출력할 내용을 작성할 때마다 개행 문자를 넣어야 하는건 너무 귀찮다. 이럴때 사용하는 명령어가 printIn()이다.

ln은 line을 의미하며 println()은 '프린트 라인'이라고 읽는다.

public class Main{
    public static void main(String[] args){
        System.out.println("Hello");
        System.out.println("Java");
    }
}


2.2. 입력 받기

출력이 명령을 실행한 결과를 보여주는 것이라면, 입력은 명령을 실행하는데 필요한 데이터를 넣어주는 것이다.

 

2.2.1. read()로 입력받기

대표적인 입력 명령어로는 read()가 있다.

출력 명령어와 마찬가지로 형식이 정해져 있으며, 아래의 명령문처럼 쓴다. 의미는 '키보드로 값(데이터)를 입력받아라'이다.

System.in.read()

 

read() 명령어는 값을 읽어만 오기 때문에, 값을 어딘가에 저장해야한다. 

-> 이 부분은 3장에서 배우므로(=아직 안 배웠음) 여기서는 출력 명령어와 함께 사용하는걸로 대체한다.

 

위의 코드는, 키보드로 값을 읽어와서 화면에 출력하라는 의미이다.

그런데 read 부분에서 오류가 발생하고 있다. Unhandled exception: java.io.IOException

 

프로그램을 실행하다 보면 문제가 발생해 프로그램이 멈추는 경우가 있다. 이때 발생하는 문제는 2가지이다.
1) 오류(error)
2) 예외(exception)

오류는 예측하기 어렵지만, 예외는 예측해서 처리할 수 있다. 자바는 예외에 대한 처리 방법을 지원하며 때문에 예외 처리가 되지 않으면 위처럼 경고 메시지를 출력한다.

 

자바는 입력 명령어(read같은)를 사용할 떄 값이 잘못 입력되는 오류가 발생하지 않도록 필수로 예외처리를 요구한다. 이 예외 처리를 어떻게 하는지 살펴보자.

read에 마우스를 가져다된 뒤 "Add exception to method signature"을 클릭하자.

-> 그러면 맨 위에 import java.io.IOException;과 main() 메서드 뒤에 throw IOException(예외 거르기)이 추가된다.

-> 자바에서 입출력과 관련된 예외 처리는 IOExceprion 클래스에서 담당한다

(자세한 예외 처리는 9장에서 다루니, 여기서는 해당 클래스가 입출력에서 발생하는 예외처리를 담당한다는 것만 알고 넘어가자)

 

 

2.2.2. import

자바에서 패키지(package)는 클래스와 파일 등을 하나로 묶은 단위이다. 폴더라고 생각하면 이해하기 편하다.

IOExcetion 클래스는 java.io 패키지에 포함되어있다.

 

다른 패키지에 속한 클래스를 사용하려면 현재 클래스명 앞에 해당 패키지 명을 모두 붙여야하는데 이건 너무 귀찮으므로 이 과정을 간소화 하기 위해 import 작업을 한다.

클래스 위에 아래 형식으로 import하면 다른 패키지의 클래스를 불러와 사용할 수 있다.

import [패키지명].[클래스명];
//import java.io.IOException

 

 

 

2.2.3. Scanner 클래스 사용 배경

위에서 작성한 코드이다. 이때 코드를 실행하고 1을 입력하면 출력값이 49가 나오는데 왜그러는지 살펴보자.

import java.io.IOException;

public class Main{
    public static void main(String[] args) throws IOException {
        System.out.println(System.in.read());
    }
}

 

 

1을 입력했는데 49가 나오는 이유는, read() 명령어가 입력값을 ASCII 코드로 받아서 그렇다. ASCII 코드는 알파벳이나 숫자 등을 컴퓨터가 이해할 수 있게 변환(인코딩)할때 사용한다. 숫자 1은 아스키 코드에서 10진법으로 49이므로 49가 출력된 것이다.

 

또한 read() 명령어는 1바이트만 읽어오기 때문에 123을 입력하면 1만 반환한다.

참고로 숫자 & 알파벳 = 1바이트, 한글 1글자 = 2바이트

 

read() 명령어를 사용하면서 입력한 그대로 1을 출력하고 싶다면 입력 명령어 System.in.read() 앞에 (char)을 추가하면 된다.

import java.io.IOException;

public class Main{
    public static void main(String[] args) throws IOException {
        System.out.println((char)System.in.read());
    }
}

/*
1
1
*/

 

 

 

2.2.4. Scanner 클래스로 입력받기★

자바는 입출력이 스트림을 통해 이루어진다. 스트림(Stream)은 입출력 장치와 프로그램을 연결하는 통로이다.

스트림을 통해 입력장치로 입력한 값은 프로그램으로 전달되고, 프로그램을 실행한 결과는 출력 스트림을 통해 출력 장치에 표시된다.

-> 스트림에는 '물줄기'라는 뜻이 있는데, 물줄기가 한 방향으로만 흐르듯 스트림도 한 방향으로만 전달이 가능하다. 

-> 그래서 입력과 출력 스트림이 따로 존재한다.

 

입력 명령어를 사용할 때 나온 System.in이 입력 스트림이며, 마찬가지로 System.out이 출력 스트림이다. 

(입출력 스트림에 대한 자세한 내용은 11장에서 배우니 가볍게 읽고 넘어가자)

read()는 1바이트만 읽어올 수 있으므로, 자바에서는 값을 입력받을때 주로 Scanner 클래스를 사용한다.
Scanner 클래스를 사용하면 다앙햔 형태의 값을 입력받을 수 있다!

 

 

Scanner 클래스는 아래와 같은 형태로 사용한다. Scanner 클래스로 값을 입력받아 프로그램에서 사용하려면 이 값을 어딘가에 저장해야하는데, 이 역할을 하는 것이 변수이다. 여기서는 scan이 변수에 해당한다.

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in); //Scanner 부분
        System.out.println(scan.nextLine()); //출력 부분
        scan.close
    }
}

/*
안녕안녕
안녕안녕
*/

 

//Scanner 부분

-> 등호 이전의 Scanner scan은 Scanner의 객체 이름이 scan임을 명시한다는 의미이다

-> 등호 이후의 new Scanner(System.in)의 new는 메모리에 새로운 Scanner 객체를 생성하겠다는 키워드이다.

 

//출력 부분

-> nextLine()은 Scanner 클래스에 속한 명령어로, 값을 한 줄 단위(사용자가 Enter을 치기 전까지)로 입력받는다. 값을 가져오는 대상은 앞에서 만든 scan 변수이다.

-> 추가로 next()는 입력받은 내용 중에서 공백 문자 전까지만 출력한다(ex. Hello world -> Hello)

-> 추가로, Scanner 클래스로 입력 스트림을 사용하다가 사용이 끝나면 close() 명령어로 닫아주는 것이 좋다. 닫지 않으면 계속해서 자원을 사용하는 상태가 되어 메모리가 낭비되기 때문이다.


2.3. 퀴즈☆

read()로 숫자를 123을 입력받아 그대로 출력한다고 했을 때 , 1~3에 들어갈 코드를 완성해보시오.

 

생각)

123이 변수에 저장되는것도 아닌데, 어떻게 각각의 명령어가 1,2,3을 순차적으로 출력하지...?

 

풀이)

입력한 123\n은 버퍼에 저장되며, read는 버퍼에서 한 바이트씩 꺼내오는 방식으로 동작한다.

-> 입력 후 바로 출력되는 것 처럼 보이지만, 사실은 입력된 데이터를 순차적으로 처리하는 과정이다!

import java.io.IOException;

public class Main{
    public static void main(String[] args) throws IOException{
        System.out.print((char)System.in.read()); //(1)
        System.out.print((char)System.in.read()); //(2)
        System.out.print((char)System.in.read()); //(3)
    }
}

 

추가로 Scanner을 사용하면 아래의 코드처럼 작성하면 된다.

import java.io.IOException;
import java.util.Scanner;

public class Main{
    public static void main(String[] args) throws IOException{
        Scanner scan = new Scanner(System.in); //입력 받고
        System.out.println(scan.nextLine()); //입력받은 scan 객체를  출력한다
    }
}

2.4. 마무리

1) 입력과 출력

2) 출력 명령어 - print, printf, println

3) read() - 값을 1바이트씩 읽어오며 기본적으로 값을 아스키 코드로 출력. 이를 char로 바꿔야 문자 출력 가능

4) 입출력 스트림

5) Scanner 클래스


2.5. 셀프 체크★★

앞에서 배운 명령어를 사용해 실행 결과처럼 내용을 입력받아 출력하는 코드를 작성해 보세요.

 

내가 짠 코드) 틀린건 아님

각 문장을 서로 다른 변수로 두어야할 것 같아서 scan1, scan2, scan3로 나누어 입력받음

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner scan1 = new Scanner(System.in);
        System.out.println(scan1.nextLine()); //println()을 사용하는거 잊지 말기

        Scanner scan2 = new Scanner(System.in);
        System.out.println(scan2.nextLine());

        Scanner scan3 = new Scanner(System.in);
        System.out.println(scan3.nextLine());
    }
}

 

 

 

정답 코드)

입력 받는 코드를 한 번만 작성하고, 출력 명령어를 연속으로 3번 작성함

 

이해가 잘 안되었던 부분)

코드는 위에서부터 아래로 해석되니, System.in에서 입력받은 문자열을 3번 반복해서 출력해야하는 것 아닌가?

-> Scanner sacn = new Scanner(System.in)에서 입력을 받는 것이 아님!! 이 부분은 입력 받을 준비를 하는거임

-> 첫 번째 nextLine()이 호출되면, 프로그램은 입력을 기다리는 상태로 멈춤

-> 사용자가 키보드 입력 후 Enter을 치면 입력 버퍼에 데이터가 저장되고 println()에 의해 데이터가 출력된다

-> 두 번째 nextLine()을 해석할 때도 위와 같이 작용한다.

-> 따라서 System.in에 의해 입력을 받을 수 있는 상태가 되며, 각각의 nextLine()에 걸릴 때마다 입력 대기, 출력을 한다.

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        System.out.println(scan.nextLine());
        System.out.println(scan.nextLine());
        System.out.println(scan.nextLine());
    }
}

Scanner scan = new Scanner(System.in)
: System.in이라는 입력 스트림을 Scanner 객체에 연결하는 코드이다. 즉 입력 받을 준비만 하는 것이다
-> System.in에 속아 입력을 받는다는 생각은 버리자.. System.in은 키보드로부터 입력을 받을 수 있도록 연결된 입력 스트림이다!!!

System.out.println(scan.nextLine())
: 실제로 입력을 받는 부분이다. nextLine()이 호출되는 순간 입력을 기다리는 대기 상태가 되며, 입력 후 Enter을 누르면 버퍼에 저장된 데이터를 출력한다.
-> Scanner은 입력을 받는 도구일 뿐이며, nextLine(), next() 같은 메서드들이 실제로 입력을 처리한다.

'Language > Java Language' 카테고리의 다른 글

6장 - 여러 값 한 번에 저장하기: 배열  (1) 2025.03.05
5장 - 같은 작업 반복하기: 반복문  (1) 2025.02.19
4장 - 조건에 따라 흐름 바꾸기: 조건문  (0) 2025.02.16
3장 - 기초 문법 배우기  (0) 2025.02.13
1장 - Hello, Java!  (1) 2025.02.11
'Language/Java Language' 카테고리의 다른 글
  • 5장 - 같은 작업 반복하기: 반복문
  • 4장 - 조건에 따라 흐름 바꾸기: 조건문
  • 3장 - 기초 문법 배우기
  • 1장 - Hello, Java!
sonotri._.
sonotri._.
@-@
  • sonotri._.
    SONOTRI
    sonotri._.
  • 전체
    오늘
    어제
    • 분류 전체보기 (102)
      • CTF (4)
      • Wargame (11)
      • Infomation_Sec (2)
      • Cyber_Sec (11)
        • Linux Kernel (2)
        • webhacking.kr (3)
        • bandit (4)
        • GoN Club Study (2)
      • Language (8)
        • C Language (2)
        • Java Language (6)
      • Dreamhack (43)
        • System Hacking (8)
        • Reverse Engineering (11)
        • Web Hacking (2)
        • Embedded Hacking (16)
        • Digital Forensics (0)
      • Basic_Theory (11)
      • elif (3)
  • 링크

    • Github
  • 인기 글

  • 최근 글

  • 공지사항

  • 태그

    초기화
    vmware 네트워크
  • 최근 댓글

  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • hELLO· Designed By정상우.v4.10.3
sonotri._.
2장 - 입출력 다루기
상단으로

티스토리툴바