앞에서, 우린 문자와 숫자의 키보드를 입력할때의 처리과정을 알아보았다. 다음은, 문자열이다.

System.in.read() 부분은, 하나의 문자만을 입력, 저장, 출력을 했다. 그렇다면, 여러개의 문자로 구성된 문자열은 어떻게 되는가?

첫번째 방법은, byte 형의 배열을 사용하는 방법이 있다.
1//   import java.io.*;
2//    class Exam04_06{
3//        public static void main(String[] args) throws IOException{
4//            byte[] by = new byte[10];
5//            System.out.print("Subject = ");
6//            System.in.read(by);
7//            System.out.println("So, Subject = " + new String(by));
8//        }
9//    }
4번째 라인에서 byte 형의 배열 ny 를 선언하고, 6번째 라인에서 입력 받은 것을, 배열 by 에 저장한후, 7번째 라인에서 출력한다. 이건 나중에 배열 부분에서 알아보기로 하고, 두번째 방법으로 들어가 본다.

두번째 방법은 다음 구문을 사용하는 것이다.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in))
이 구문을 사용한 코딩은 다음과 같다.
1//    import java.io.*;

2//    class Exam04_07 {
3//        public static void main(String[] args) throws IOException {
4//           BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

5//           String name = "";
6//           String age = "";

7//           System.out.print("Name = ");
8//           name = in.readLine();
9//           System.out.print("Age = ");
10//           age = in.readLine();

11//           System.out.println();
12//           System.out.println("Name = " + name);
13//           System.out.println("Age =" + age + " years old");
    }
}
4번째 라인에서 쓰인 구문은, 훗날 분석을 하기로 하고, 지금은, 단지, 구문 자체를 외우는게 나은 방법이다.

String 형의 변수를 선언, 초기화 시켜주고, 7번째 라인에서, 이름을 물으며, 입력을 받는다. 이 입력을 받아서 저장하는 역할을 하는게 8번째 라인이다.

in.readLine() 은, 문자열을 입력받아, 저장, 출력을 해주는데, 전에 배운, System.in.read() 와는 달리, .이 in.readLine() 은, 엔터키가 입력되기 전까지의 문자들을, 입력받아 저장시켜준다. 그래서, System.in.read() 에서 했던, 엔터키를 무력화시켜주는 기법이 여기서는 따로 필요가 없다.  또한 이 구문은, 위의 BufferedReader in 에서 가져와 in.readLine(); 으로 사용하고 있다. 만약 BufferedReader rys 라고 하면, rys.readLine() 이라고 바꿔줘야 할 것이다. 이를 이용하면, 앞에서 봤던 예제에서, 엔터키값을 없애기 위해 사용한 System.in.read() 를 사용안하고, 여기서 배운 내용으로, 코드를 수정, 보완할수가 있다.

하 지만 여기서도, 한가지 문제점이 발생한다. 바로, 여기서는 문자열만이 저장된다는 된다는 것인데, 숫자열을 하고 싶다면 어떻게 해야 하나. 물론, 위의 코딩대로 해도, 오류는 나오지 않는다. 다만, 이를 문자열로 저장하고, 문자로 인식하며, 쓸데없는 공간들을 낭비하는 문제가 따로 발생할뿐이다.

아무튼, 숫자열을 사용하고 싶다면?? 이때는 Wrapper 클래스라는 것을 사용한다.
1//    import java.io.*;

2//    class Exam04_08 {
3//        public static void main(String[] args) throws IOException {
4//           BufferedReader in = new BufferedReader(new InputStreamReader)(System.in));
      
5//           String imsi = "";
6//           byte a = 0;
7//           int b = 0;
8//           float c = 0.0f;
   
9//           System.out.println("Insert Numbers : ");
10//           imsi = in.readLine();

11//           a = Byte.parseByte(imsi);
12//           b = Integer.parseInt(imsi);
13//           c = Float.parseFloat(imsi);

14//           System.out.println("a = " + a);
15//           System.out.println("b = " + b);
16//           System.out.println("c = " + c);
    }
}
여 기서 11번째 라인서부터 13번째 라인까지가, Wrapper 클래스이다. 그래서 9번째 라인과 10번째 라인에서 문자열을 입력받은 후, 이 입력받은 값을, 숫자로 바꿔주는 역할을 하는게, 11번째 라인에서 13번째 라인까지의 Wrapper 클래스 이다.


p.s 위의 글들은, 김승현 강사님열혈강의 Java Programming 의 Round 4-3, 동영상 강좌에 기초한 내용입니다.
:
키보드를 통한 입력은 크게 두가지로 나눌수 있다.

1. 문자 및 숫자 입력
2. 문자열 입력

첫번재 문자 및 숫자 입력은, 또 3가지 형태로 나눌수 있다.

(1) 아스키 코드 값을 읽어내는 방법
(2) 숫자값을 읽어내는 방법
(3) 문자값을 읽어내는 방법

다음의 코드를 살펴보자.
1//    import java.io.*;

2//    class Exam04_05 {
3//        public static void main(String[] args) throws IOException {
4//           System.out.print("Insert Character: ");
5//           int a = System.in.read();             // 아스키 코드값으로 저장, 출력.
6//           //Char a = (char)System.in.read();    // 문자값을 그대로, 저장, 출력.
      
7//           System.out.println("a = '" + a + "'");

8//           System.in.read();             // 엔터중 \r을 무효화 시키는 부분
9//           System.in.read();             // 엔터중 \n을 무효화 시키는 부분

10//           System.out.print("Insert Number : ");
11//           int b = System.in.read() - 48;   // 숫자값을 저장할때, 혹은 '0' 을 대신 사용가능

12//           System.out.println("b = " + b);
    }
}
System.in.read() 는 기본적인 입력을 담당하는 메소드이다. 이 메소드를 사용하는 방법은 위에서 말한대로 3가지 방법이 존재하는데, 이 메소드는 1바이트만 입력이 가능한 메소드로, 이후, 지속적인 타이핑을 해도, 입력받아 저장하는 값은, 처음으로 타이핑을 한 글자만이 입력되고, 저장된다. 또한, 아스키 코드값을 읽어, 사용하는 메소드이다. 그리고, 이 값은, 키보드 하나에 매칭(엔터제외)된다. 즉, System.in.read() 는 키보드를 한번 타입할때마다 메소드 하나가 실행이 된다고 보면 된다는 것이다.(엔터제외)

먼저, 1번째라인부터, 7번째 라인까지 한 결과를 알아보는데, 여기서 6번째 라인은 주석 처리하여, 실행이 안되도록 막아놓는다. 물론, 기타, 8번째부터 12번째 라인, 역시 주석으로 막아놓는다.

이 첫번째 케이스에서는 타입한 키보드 값의 아스키 코드 값을 읽어, 저장, 출력한다.

사용자 삽입 이미지

r 을 입력받아, r의 아스키 코드 값은 114가 출력이 되었다. 만약, 여러문자를 입력하면?

사용자 삽입 이미지

이렇듯, 여러문자를 입력해도, 첫번째 입력된, r 만의 값을 저장, 출력한다. 그래서, 결과는 위와 똑같다. 숫자를 입력하게 되면 어떻게 될까?

사용자 삽입 이미지

숫자 5를 입력하면, 숫자 5에 해당하는 아스키 코드값을 읽어들여, 저장, 출력한다. 그 값이 바로 53.

System.in.read() 를 사용하면, 이렇듯, 아스키 코드값만을 읽어들여, 저장, 출력한다. 그러면, 만약, 받은 문자값을 그대로, 읽어들여, 출력하게 하고 싶다면???

위의 코딩부분으로 가서, 라인 1부터 7에서, 6의 주석을 풀어서, 사용가능하게 만들고, 라인 5에다가 주석을 붙여서, 사용가능하지 못하도록 만든다. 그외의 라인 8부터 12는 사용 못하도록 주석처리를 한다.

사용자 삽입 이미지

문 자값을 그대로 입력받아, 그대로 출력을 할때는, 위의 라인 6처럼, (char)System.in.read() 를 사용해 준다. 이는, System.in.read() 로 입력받은, 아스키 코드 값은 정수를, 문자형태로, 형변환을 시켜준 것이다. 이렇게 해줌으로써, 무사히, 문자값을 그대로 입력받아, 그대로 출력할수가 있게된다.

만약, 여기서, 숫자를 입력하게 된다면? 숫자 역시, 그대로 입력을 받아, 그대로 출력이 가능하다. 하지만, 여기서의 숫자는 엄밀히 말하면, 정수, 혹은 실수개념의 숫자가 아닌, 문자형태의 숫자로 컴퓨터가 인식하게 된다. 다시말해, 컴퓨터가, 문자로 판단한다는 것. 물론, 그게 숫자형태를 띄고 있다고 해도 말이다. 왜냐면, 코딩 부분을 보면, char 형태로 변수를 선언했으며, 형변환도, char 형태로 형변환을 했기 때문이다.

그러면, 순수한 형태의 숫자를 사용하려면 어떻게 해야 할까?

위의 코딩부분에서, 1, 2, 3, 10, 11, 12 라인만을 이용하면 된다. 다른 부분은 주석처리하자. 이것의 결과는 이렇게 나온다.

사용자 삽입 이미지

여 기서 핵심라인은 11번쨰 라인이다. System.in.read() 부분은 아스키 코드값을 다룬다고 했다. 여기서, 5의 아스키 코드값은, 위에서 보았듯이 53이다. 숫자 0의 아스키 코드값은 48이다. 고로, 입력받은 숫자의 아스키 코드값에서, 0의 아스키 코드값은 48을 빼면, 입력받은 숫자, 그대로 출력될 것이다. 예를 들어, 위의 예에서, 5를 입력하면, 아스키 코드값은, 53이 입력, 저장되고, 여기서, 0의 아스키 코드값인 48을 빼면, 5, 입력한 숫자 5가, 그대로 출력하게 되는 것이다.

그래서, 코드란에, System.in.read() - 48; 이라고 코드를 적어놓았다. 이 방법말고도, 그대로 작은 따옴표 '' 를 사용해서 '0' 을 48 대신에 사용해도 된다. 작은 따옴표를 쓰면, 문자값을 그대로 쓰지만, 내부에서는, 문자값의 아스키 코드값을 읽어들이기 때문이다.

이번엔 좀더 응용을 해보자.

위의 코딩부분중, 5, 8, 9 라인을 모두 주석 처리하고, 나머지 부분은, 주석을 제거해서 실행을 시켜보자.

사용자 삽입 이미지

이렇게 이상한 값이 출력하게 된다. 왜 그런 것일까?

System.in.read() 라는 메소드는, 키보드 한번 타입할때마다, 하나가 실행된다고 했다. 위에 4번라인에서 입력을 받아, 6번 라인에서 저장하고, 그리고, 나서 출력을 해야 되는데, 다시 말하지만, System.in.read() 라는 메소드는, 키보드 한번 타입할때마다, 하나가 실행된다고 했다. 위에서, 키보드를 몇번 입력했는지를 곰곰히 생각해보면, 해답이 나온다.

위에서, "r" 이라는 키보드를 타입하고, 또, "엔터" 라는 키보드를 타입했다. 이렇게 총 두번 키보드를 타입했으며, 코드 안에는, System.in.read() 라는 메소드가 두번만 실행이 된다. 즉, 첫번째, System.in.read() 부분에는 "r"이 들어갔으며, 두번째, System.in.read() 라는 메소드에는 "엔터" 부분이 들어가서 실행이 된것이다. "엔터"의 아스키 코드값은, 13이며, 라인 11의 System.in.read() - 48 이라는 부분에 의해 13-48이 연산, -35가 출력이 되는 것이다.

이러한 현상을 없애기 위해서, 첫번째, System.in.read() 와 두번째, System.in.read() 사이에, 엔터값을 먹어주는 또하나의 System.in.read() 라는 값이 들어가야 하는데, 그렇게 해서, 라인 8의 주석을 해제 시켜서, 컴파일을 해보자.

사용자 삽입 이미지

근 데, 이상하게 또다른, 이상한 값이, 바로 출력된다. 위에서 잠깐 언급했었는데, 실제 엔터는, \r 과 \n 이라는 부분으로 이루어져있다. 그래서, 만약, 위에서 한대로, 라인 8의 주석만을 해제 시키면, 엔터를 구성하는 요소중, \r 부분만이 먹히게 되고, \n 부분의 아스키 값은, 그대로, 컴퓨터가 인식하여, 출력되게 되는 것이다.

고로, 라인 8과 라인 9의 주석을 모두 해제를 시킨후에 실행을 시키면, 제대로 실행되는 것을 보게 될것이다.

사용자 삽입 이미지


p.s 위의 글들은, 김승현 강사님열혈강의 Java Programming 의 Round 4-3, 동영상 강좌에 기초한 내용입니다.
:

BLOG main image
아무거나 공부하자!!! by Young79

공지사항

카테고리

분류 전체보기 (79)
Programing (29)
English (31)
Graphic (4)
Saying on T"We"tter (15)

최근에 올라온 글

최근에 달린 댓글

글 보관함

달력

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total :
Today : Yesterday :