하루종일 영어만 보기 너무 심심해서 대학교 다닐때 봤던 자바책을 다시 보기 시작했다..
제목은 "명품 JAVA Programming"

-표지사진, 표지와 내용 모두 칼라다.-
서울에 있을때 친구한테 받은 것 같은데 기억이 가물가물하다.
그냥 모셔만 두고 예제만 몇번 본게 전부다.
개념정리는 잘 되어 있는 것 같다.
이해하기 쉬운 그림과 차분한 어조로 설명해서 특히 좋은 것 같다. 개인적으로.
처음부터 보니 자바에 대한 소개 부분 있어서 계속 보던 중 Scanner클래스에 대해 연습하는 예제문제가 나왔다.
- Scanner를 이용하여 2개의 정수를 키보드로 입력받아 두 수의 합을 출력하는 프로그램을 작성하라.
- Scanner를 이용하여 키보드로부터 임의의 문자열을 입력받고, 이 중 공백으로 분리된 단어들을 출력하고 입력된 단어의 개수를 출력하는 프로그램을 작성하라.
-예제문제-
1번을 가뿐하게 작성한 후 2번을 작성하던 중 어려움에 봉착했다.
입력된 단어의 개수를 출력해야 하는데 정확한 해결방법이 떠오르지 않아 슬쩍 답을 보았다.
일일이 생각하기 귀찮으니 빨리 답을 코딩 후 컴파일 했다.
CheckTime 문제 해답코드
Scanner sc = new Scanner(System.in);
int count = 0;
while(sc.hasNext()){
String word = sc.next();
System.out.println(word);
count++;
if(word.equals("exit")){
break;
}
}
System.out.println("단어 개수 = " + count);

.. 음? ..
이건 아닌거 같은데.
명제 그대로 구현하려면
1. 공백으로 분리된 단어들을 출력하고(AND조건 ㅋㅋ)
2. 입력된 단어의 개수를 출력
위 2가지가 한 큐에 다 되어야 하는데 계속 입력 대기상태...ㅡㅡ.. while문 종료가 안되는 것 같다.
while(sc.hasNext()) 부분에서 hasNext() 메소드가 false를 반환해야 while문이 종료되는데 그게 안되는 것 같다.
인터넷으로 찾아보던 중 Scanner while문 종료 관련하여 StackOverFlow에 올라온 질문을 보았다.


-스택오버플로우 질문과 답-
입력대기 상태에서 "exit"를 입력하여 반복문을 빠져 나오는 방법이 있다고 서로 굳 벝 온리이프 블라블라.
근데 "명품자바"는 "exit"같은 명령을 입력하라고 명시하지 않았다.
분명 "공백으로 분리된 단어를 출력" 하고 이어서 "입력된 단어의 개수를 출력" 하라고 나와있다. 모두 나와야 한다. 출력AND출력.

-스택오버플로우 질문 답변 적용한 코드, exit 입력하면 while문 종료됨 -
제시된 문제가 이상이 있나 싶어서 짜증나서 그냥 냅다 문제를 구글에 검색해봤다.

-구글 검색-
ㅎㅎㅎ.. 똑같은 예제와 거의 비슷한 코딩을 ppt파일로 올려놓았다. 어디 한번 볼까-.

- 검색된 ppt 파일 --;;; -
책이랑 똑같다. ㅡㅡ 이거 그대로 컴파일 해 보니 역시나 단어 개수는 안 나온다...
ctrl+z, ctrl+d 같은거 눌러봐도 안 된다.
이건 InputStreamReader클래스의 read()메소드에서 ctrl+z(windows계열), ctrl+d(Unix, Linux계열) 입력을 지원한다고 한다.
명품자바는 제시한 문제에서 Scanner클래스를 사용하라고 했다. ㅋㅋ 다른 클래스는 거부한다.ㅋㅋㅋ
JAVA API를 받아서 Scanner클래스를 검색해 봤다.
SE 6버젼 한글판이 있길래 다운 받았다. 실제 코딩에 사용된 버젼은 JDK 1.7.0_71 버젼이지만 거의 같을것이라 생각된다.
-API 내용-
한글인데도 뭔 말인지 깊게 이해하기 힘들다. 자바나 영어를 잘 이해했으면 이런 일은 없을텐데...
어서 영어랑 자바실력을 높여야지. ㅠ,.ㅠ
그 중 next()메소드의 설명이 조금 길다.
이 스캐너로부터 다음의 완전한 토큰을 검색해 돌려줍니다. 완전한 토큰의 전후에는, 단락 문자 패턴에 일치하는 입력이 배치됩니다. 이 메소드는, 전의
hasNext() 의 호출로 true 가 돌려주어졌을 경우에서도, 입력의 스캔의 대기중에 블록을 실행할 가능성이 있습니다. 아.. 저장된 값의 위치를 토큰이라고 표현하는 건가?
... hasNext() 메소드가 true를 반환했을 때 next() 호출 시 입력대기 상태를 유지한다 뭐 그런 얘기인 것 같다.
내가 정말정말 알고 싶은 부분은 while(sc.hasNext()) 부분에서 분명 객체 "sc"의 토큰 중 값이 없는 토큰순서가 왔을 때
false를 반환하며 while문이 종료되어야 하는데 그게 안된다는 것이다. while문 종료가 안됨..
System.out.println(""); 으로 값을 출력해 보니 반복문 마지막 순서에서 false가 반환되지 않았다.
검색해 보니 EOF(End of File) 이야기가 나왔다. 이게 무슨 연관이?
"hasNext()"를 검색하다 보니 아래 예제를 발견했다.

- Scanner.hasNext() 예제 -
- 출처 : http://www.tutorialspoint.com/java/util/scanner_hasnext.htm -
위 예제에서는 false가 반환된다.
하지만 책에서 주어진 예제에서는 false가 반환되지 않는다.
Scanner클래스에 System.in 입력방법과 String type의 변수를 입력하는 방법에 차이가 있었다.
그럼 정리 해 보자면
---------------------------------------------------------------------------------------------------------------------------------------------
Scanner클래스의 입력변수로 BufferStream이냐 String 변수냐에 따라 처리가 다름.
값이 저장된 하나의 String Type의 변수는 hasNext() 메소드가 false 값을 리턴하고
BufferStream은 입력 대기하는 상태가 되기 때문에 종료되지 않았다...?
---------------------------------------------------------------------------------------------------------------------------------------------
.......
아무튼 String Type으로 문자열 완성하여 Scanner클래스에 입력하면
hasNext()가 객체에 다음 토큰이 없을 경우 "false"를 반환한다는 사실을 Scanner.hasNext() 예제 테스트를 통해 추측할 수 있었다.
코드를 수정하면서 쓸 만한 예제를 하나 찾아서 참고하였다.

-출처 : http://chokso1.blogspot.kr/2013/07/scanner.html -
Scanner 클래스를 2개 선언하여 하나는 키보드 입력 역할을 하고 다른 하나는 입력된 값을 받아 hasNext(), next() 메소드를 사용하
는 역할로 만들었다.
컴파일 하고,
"사과 배 바나나" 를 입력하고 "엔터"를 쳤다.
1 | package chapter2; |

-완성된 코드 화면, 결과화면-
이렇게 해서, 문제에 최대한 만족하는 코드를 작성한 것 같다.
명품 자바 프로그래밍 77p CheckTime 문제 2번 해답은 위와 같은 소스코드가 정답에 가까운 듯 싶다.
혹시 다른 방법이 있는지 궁금하지만 귀찮아서 그냥 넘어가야 겠다.
> 아래 댓글에 더 좋은 예제가 있다. 감사합니다 !




덧글
네.. 맞아요.. 답안상에는 exit 로 종료하면 되지만, 심심해서.. 별도의 커맨드 없이 제시된 문제 "그 대 로" 해보려고 한거에요 ㅎ
public class example1 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(true){
System.out.println("문자열들을 입력하세요: ");
String str= scan.nextLine();
String words[] = str.split(" ");
for(int i = 0; i < words.length; i ++)
{
System.out.println(words[i]+" ");
}
System.out.println("입력된 단어의 수 : "+ words.length);
break;
}
}
}
이렇게 코드를 짰는데, 작성하신 가장 마지막 코드랑 비교했을 때, 혹시 제 코드에서는 원하는 구현을 못하게 되는 문제가 있을까요??
제 예제를 보니 Scanner 클래스만 생각하고 작성한 것 같습니다. 간단한 방법을 두고 복잡하게 작성했었네요..
split() 함수와 배열변수 사용으로 코드 이해가 더 쉬운 것 같습니다.
짝짝짝 ~