Java

입력과 출력

 

이전 시간에 메소드에서의 입력과 출력에 대해서 알아봤다. 이를 통해서 메소드가 좀 더 쓸모 있는 것이 될 수 있다는 것도 알게 되었을 것이다. 그럼 자바 에플리케이션도 입력과 출력을 할 수 있을까? 물론이다. 예를들어 사용자의 키보드, 마우스, 터치를 입력으로 받아들일 수 있고, 그에 따른 처리 결과를 모니터나 스피커등으로 출력 할 수 있다. 입력 값이 없는 에플리케이션은 입력 값이 없는 메소드처럼 똑같은 결과를 반복하는 것에 불과하다. 이번 시간에는 입력 값을 에플리케이션에 전달해서 좀 더 생동감있는 에플리케이션을 만들어보자.

String[] args

지금까지 미지의 영역으로 남겨두었던 Strings[] args의 의미를 파헤쳐 볼 시간이다. 아래 예제를 보자.

package org.opentutorials.javatutorials.io;

class InputDemo{
    public static void main(String[] args){
        System.out.println(args.length);
    }
}

아시다시피 main 메소드는 자바에서 특별한 의미를 가진 메소드다. main 메소드의 내용을 구현하면 자바 에플리케이션을 실행할 때 main 메소드가 호출되면서 프로그램이 구동하게 되는 것이다. 이 때 Strings[] args는 입력 값의 파라미터로 동작한다.

String[] args은 매개변수다. 매개변수는 메소드가 호출될 때 전달된 입력 값을 메소드 내부로 전달하는 역할을 하는 변수다. 이 변수의 데이터형은 String[]인데, String[]은 문자열을 담고 있는 배열이다. args.length는 배열의 길이를 의미한다. 이 점을 기억하고 위의 코드를 실행해보자.

javac InputDemo.java
java InputDemo 1 2 3 4 5 6;

결과는  6이다.

java InputDemo one two three;

결과는 3이다. 

이것을 통해서 추론 할 수 있는 것은 자바 에플리케이션 실행 명령인 java InputDemo 뒤에 따라오는 값의 숫자 만큼 변수 args에 어떤 값이 들어있다는 점이다.

그 값을 확인해보자.

class InputForeachDemo{
    public static void main(String[] args){
		for(String e : args){
			System.out.println(e);
		}
	}
}

위의 예제는 for-each 구문을 이용해서 변수 args에 담긴 값을 한줄씩 출력하고 있다.

즉 자바 에플리케이션에서는 메소드 main의 인자 String[] args를 통해서 사용자가 입력한 값을 전달하고 있다는 것을 알 수 있다.

조건문 수업에서 로그인 에플리케이션을 만든 것을 기억할 것이다. 해당 수업으로 다시 돌아가서 예제를 음미해보자. 더 많은 것이 보이지 않는가? 아는 만큼 더 많은 것이 보이는 것이 공부의 즐거움이 아닐까?

앱이 실행중에 입력 받기

이번에는 자바앱이 실행되고 있는 동안에 사용자의 입력을 받는 법을 알아보자. 자바에서 기본적으로 제공하는 라이브러리 중에 scanner을 이용하면 쉽게 사용자의 입력을 잡을 수 있다. 

안타깝게도 우리는 아직 라이브러리나 패키지와 같은 개념을 배우지 않았다. 아직은 이 로직을 샅샅이 이해하는 것은 무리이기 때문에 입력을 받는 방법에 대한 전체적인 흐름을 파악하는데 집중하자.
package org.opentutorials.javatutorials.io;

import java.util.Scanner;

public class ScannerDemo {

    public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int i = sc.nextInt();
		System.out.println(i*1000);
        sc.close();
	}

}

위의 예제를 실행하고 숫자를 입력하면 입력한 숫자의 1000배가 출력 될 것이다. 예제에서 우리가 주목해야 할 부분은 sc.nextInt()가 실행되면 자바는 사용자의 입력이 있을 때까지 변수 i에 값을 할당하지 않고 대기상태에 있게 된다. 키보드로 데이터를 입력하고 엔터를 누르면 비로서 i에 값이 담기고 i*1000을 통해서 입력값에 1000이 곱해지고 그 결과가 화면에 출력된다. 

아래의 코드는 연속적으로 값을 입력 할 수 있고, 입력한 값에 1000을 곱한 결과를 출력하는 예제다.

package org.opentutorials.javatutorials.io;

import java.util.Scanner;

public class Scanner2Demo {

    public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNextInt()) {
			System.out.println(sc.nextInt()*1000); 
		}
		sc.close();
	}

}

sc.hasNextInt()는 입력값이 생기기 전까지 실행을 유보시키는 역할을 한다. 만약 입력한 값이 int 형이 아닐 경우는 false를 리턴하고, int로 표현할 수 있는 형식의 숫자형인 경우는 true를 리턴한다. 따라서 위의 코드는 사용자가 입력을 할 때가지 실행을 기다렸다가 입력이 일어나면 반복문이 동작하면서 입력값의 1000배를 곱한 수가 출력된다. 

여러형태의 입출력

사용자의 키보드 제어만이 입력은 아니다. 아래 예제는 out.txt라는 파일을 입력 받아서 화면에 출력하는 예를 보여주고 있다. 예제를 실행하려면 프로젝트의 루트 디렉토리(src와 bin 디렉토리가 위치하고 있는 경로)로 이동해서 아래와 같이 명령을 실행한다. out.txt 파일이 존재해야 한다. 이에 대한 자세한 이야기는 동영상을 참고하자.

package org.opentutorials.javatutorials.io;

import java.util.Scanner;
import java.io.*;

public class Scanner3Demo {

    public static void main(String[] args) {
		try {
			File file = new File("out.txt");
			Scanner sc = new Scanner(file);
			while(sc.hasNextInt()) {
				System.out.println(sc.nextInt()*1000); 
			}
			sc.close();
		} catch(FileNotFoundException e){
			e.printStackTrace();
		}
		
	}

}

결과는 파일의 내용이 무엇인가에 따라서 달라질 것이다. 이 또한 분명한 입력값이다. 프로그램으로 유입되는 모든 정보는 입력값이다. 

GUI

물론 입력이나 출력이 꼭 텍스트여야 하는 것은 아니다. 아래 URL에 담겨있는 코드는 자바를 이용해서 그래픽컬한 사용자 조작 수단을 만드는 방법을 보여준다. 이 예제는 복잡하기 때문에 지금은 코드의 내용을 생각하지 말자.  

Java Tutorials Code Sample - DialogDemo.java

위의 코드의 실행결과는 아래와 같다.

 

직접 실행해보고 싶다면 아래 URL의 파일을 다운받아서 실행해보자. (Java Web Start가 필요하다)

다운로드

이클립스에서 입력 값 사용하기

파일을 선택하고 Run Configuration을 선택한다. Arguments 탭에서 Program Arguments에 입력 값을 작성하면 콘솔에서 입력 값을 전달하는 것처럼 할 수 있다. 텍스트 만으로는 이해하는데 어려움이 있을 것이다. 동영상 수업을 참고하자.

시즌1을 마치며

이렇게 해서 Java 수업 시즌 1이 끝났다. 시즌 2의 핵심은 객체지향(Object Oriented Programming)이다. 자바가 PHP나 JavaScript, Python과 같은 언어보다 어려운 이유는 객체지향 때문이라고 해도 과언이 아니다. 이들 언어도 자바와 유사한 객체지향 기능을 가지고 있다. 하지만 객체지향을 모르고도 프로그래밍이 충분히 가능하다. 반면에, 자바는 객체지향을 사실상 강제한다. 객체지향을 안 쓰고도 휼룡한 Python 프로그램을 만들 수 있지만, 객체지향을 모르고 좋은 Java 프로그램을 만들수는 없다. 바로 이런 이유 때문에 Java 입문에는 더 많은 시간과 인내와 노력이 필요한 것이다.

하지만 객체지향은 프로그래밍 역사상 가장 중요한 패러다임 중의 하나다. 그리고 이러한 패러다임은 한순간 툭 튀어나온 것이 아니다. 오랜 시간, 많은 사람에 의해서, 수많은 시행착오를 경유해서 도달한 웅장한 성취라고 할 수 있다. 이러한 성취에 다가선다는 것은 설레는 일이 아닐 수 없다. 이러한 성취를 시행착오 없이, 빠른 속도로 인계받을 수 있다는 것은 기쁜 일이 아닐까? 다만, 그 성취가 너무 거대해져서 그것 흡수하는 것만으로도 벅찬 것은 후대가 짊어져야 할 고충이기도 할 것이다. 그래서 우리에게 필요한 것은 시간이다. 사람에게는 어떤 일을 시작하기 전에 그 일을 완수하기 위한 시간을 배정하는 습관이 있는 것 같다. 그 시간을 너무 짧게 잡으면 그 시간을 다 사용했을 때 그 일을 포기하게 될 확률이 높다. 자바의 배열을 너무 작게 만들면 나중에 ArrayIndexOutOfBoundsException이 발생하는 것처럼 말이다. 필자가 부탁하고 싶은 것은 지금 생각하고 있는 것 보다 더 많은 시간을 이 일에 할당해 달라는 것이다. 당분간은 머릿속에서 수많은 개념들이 난리를 칠 것이다. 그리고 그 소동은 곧 잠잠해 질 것이다. 이것은 둘 중의 하나다. 잊어버렸거나, 완전히 내것이 되었거나.

 

댓글

댓글 본문
작성자
비밀번호
  1. circle
    java io에 관한 강의도 있으면 좋겠는데 아쉽네요 ㅠㅠ
  2. 정명호
    감사합니다.
    제가 듣기로는 계속 문제를 풀어봐야 제것이 된다고 들었네요
    제것이 되도록 노력하겠습니다.
    정말 감사합니다.
    지금 오프라인으로 듣고 있는 수업보다 훨 나은 것 같습니다.
  3. 400번째 시청자 입니다.
    수업을 들으면서 다른 것들을 응용해서 생각할 수 있는 시간을
    조금씩 가질 수 있는 수업인거 같아요. 다만 그런 부분을 바로 질문할 수 없다는게
    온라인 강의의 단점이기도 하구요.
    이번 수업도 잘 들었습니다.
  4. paskal kinar
    파일이름을 out.txt 라고 하지말고 그냥 out 이라고만 적으세요.
    텍스트문서 타입이 txt 타입이기 때문에, 이름을 out 이라고만 적으면
    최종적으로 컴퓨터는 알아서 out.txt 로 알아먹어요.

    한글문서 저장할 때 문서이름을 예를 들어 "정리목록" 이라고 하지만, 파일명은 "정리목록.hwp" 가 되는 것처럼요.
    대화보기
    • 강의 정말 잘 듣고 있습니다.
      근데 5번쨰 강의에서 while 반복문을 통해서 sc.hasNextInt()를 이용해서 정수값이
      들어오면 true이기 떄문에 while 반복문 안의 System.out.println(sc.nextInt()*1000)을 수행하잖아요
      이부분이 이해가 잘 안 되네요 ㅠㅠ sc.nextInt()은 입력을 다시 받길 기다려야 하는게 아닌가 싶어서요
      왜 sc.hasNextInt() * 1000이 아닌 sc.nextInt() * 1000인지 잘 모르겠습니다. 앞선 4번쨰 동영상에선
      sc.nextInt()로 대기하다가 enter를 주면 그 값을 받아 출력한다고 하셨는데 그럼 여기서도
      sc.nextInt()를 만나면 새로 값을 입력하길 기다려야 하는게 아닌지 헷갈리네요
    • 오랜만에 들어왔습니다. 다시 정주행 시작하겠습니다~화이팅!!
    • JustStudy
      강의 내용 하나 하나가 정말 주옥같습니다.
      고맙습니다
    • 개발자화이팅
      질문 있습니다. ^^ Scanner sc = new Scanner(System.in);
      이렇게 scanner를 사용하는 program을 debugging하는 건 좀 피곤한 일인 것 같더군요.
      예를 들어 scanner 를 2번 호출해서
      학생 이름: 홍길동
      영어 점수: 70

      이렇게 debugging 할 때마다, "홍길동"과 "70"을 입력하는 게 생각보다 많이 짜증을 유발하는 것 같습니다.
      "홍길동", "70"을 debugging할 때마다 입력할 거면, 입력하지 않고 저 input이 프로그램 실행할 때마다 들어가게 하게끔 설정하는 방법이 있나요?

      JAVA가 C, C++처럼 #ifdef같은 preprocessor를 지원 안 해서 조건문 추가해서 test code넣는 것도 방법인데,
      혹시 다른 방법이 없나해서 질문하고 싶습니다.
    • yskioi
      감사해요
    • 이고잉짱
      C,C++ 사용했던 학부생인데 자바를 독학해보려고 인터넷 검색하다가 생활코딩을 알게됐습니다!
      C언어를 독학할 땐 정말 삽질하면서 공부했는데, 생활코딩 덕에 자바는 진도가 쭉쭉 나가네요.
      정말 좋은 강의 무료로 진행해주시는 것이 너무 대단하시고 존경스럽습니다!
      기초부터 차근차근 공부하며 훌륭한 개발자가 되겠습니다 ^^ 감사합니다.
    • 문문문
      혹시 setter와 getter의 개념정리 강의는 없을까요??
      많이 헷갈리는데 , 강의정보에는 없는 거 같네요..
    • 김트라슈
      감사합니다 미드 시즌1이 끝난거 마냥 시즌2가 기다려지네요 ㅎ
    • 감사합니당 ㅁㅁㅁ
    • 찐똥구리구리
      샘이 전달하는 것도 유익하고, 전달하시는 방법도 좋아서 너무 많이 배우고 갑니다. 감사합니다. 마지막 성취와 시간에 관한 말씀은 퍼가서 좀 숙성을 시키겠습니다. ^^
    • while() 에서 ()안의 값이 true라면 제한범위가 없기떄문에 계속해서 반복되는게 아니였나요..?
      보다보니 이상하네요
    • 오빠는다르다
      감사합니다!!!! 시즌2도 화이팅!!!!!
    • ㅠㅠ
      저도 그런데 해결책이 먼가요?ㅠㅠ
      대화보기
      • 신경쓰여요
        분명 프로젝트의 루트 디렉토리에서 out.txt를 만들고 오류표시가 나지않는 코드를 작성했는데 실행시키니 이런오류가 나오네요.
        java.io.FileNotFoundException: out.txt (지정된 파일을 찾을 수 없습니다)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.util.Scanner.<init>(Unknown Source)
        at org.opentutorials.javatutorials.io.return1.main(return1.java:11)
        몇번을 디렉토리에 가서 확인을해봐도 제대로 out.txt는 제대로 만들었는데 너무 신경쓰이네요 ㅠㅠ
      • 감사합니다 그런데 args를 에이아이지에스라고 읽으시더군요. 저만 에알지에스라 읽었나요?
      • 기초에 충실하자
        //panda_90
        out.txt 파일이 해당 경로에 있는지 확인해 보세요. 현재 저장된 소스 파일 경로에 out.txt 파일이 있어야겠죠.
      • 초보
        import java.io.*;
        이걸 빼먹으신거 아닐까요??
        대화보기
        • panda_90
          좋은 강의 정말 감사드립니다.
          위에서 6/6 강의에서, Scanner3Demo의 코드를 저 이클립스에서 입력한 뒤 실행을 하였더니,
          File file = new File("out.txt"); , catch(FileNotFoundException e) 이 부분을 적어놓은 줄
          옆에 x표시가 뜨고, 위의 File, FileNotFoundException 이라는 부분에 빨간 밑줄이 뜹니다. 그리고

          Exception in thread "main" java.lang.Error: Unresolved compilation problems:
          File cannot be resolved to a type
          File cannot be resolved to a type
          FileNotFoundException cannot be resolved to a type

          at org.opentutorials.javatutorials.io.Scanner3Demo.main(Scanner3Demo.java:10)

          이렇게 뜨는데요.. 이유가 뭔지 좀 알려주실 수 있으실까요?
        • 정진석
          좋은 강의 감사합니다.
        • 최종현
          말씀대로 최대한 빠른시간안에 도달하고싶었지만 16일이 되서야 시즌1을 마무리하게되었네요.
          직장생활하면서 짬짬히 본다는것도 쉽지않네요.
          아무튼 하고싶은 공부를 하는데 너무나 큰 도움이 되어서 정말 감사드립니다 ^^
          복 받으실거에요~!
        • Byunghawk Lee
          잘보고 갑니당.
          빨리 자세한 내용에 대해 배울 수있기를 바라는 심정으로 넘어갑니다.
        • Byunghawk Lee
          잘보고 갑니다.
        • 허니버터
          잘보고 넘어 갑니다.
        • 취준생
          저는 컴공을 나왔는데도 단순한 로직구현에만 머물렀지 이렇게 자세한
          문법적인 이해를 갖지 못했었는데, 덕분에 취업 전 초심으로 돌아가서 기초부터
          다시 공부하고 있어요. 도움이 많이 되네요 감사합니다^ ^
        • 자바왕왕왕왕초보
          강의 감사합니다^^
        • 구공산호세
          시즌 1끝났습니다. 하루만에 다봤는데 지금 시간 7시 지금부터 바로 2부 시작하려합니다. 오늘 자기전까지 다 끝낼 수 있기를....아 그리고 좋은 강의 진심으로 감사합니다.
        • 자바를자바라
          저도 드디어 시즌1 끝냈군요. 예전에 먼저 끝내신분들 넘 부럽네요 ㅎ ㅠㅠ 저 역시 이곳을 조금 더 먼저 알았떠라면 하는 아쉬움이 너무 크게 남는군요. 남아있는 나머지부분들도 열심히 정독하겠읍니다 너무감사합니다
        • ssuac
          안녕하세요 이고잉님 좋은 강의 감사드립니다.

          메소드를 사용? 하는 방법에서 궁금증이 남아서 글을 남깁니다.

          while(sc.hasNextInt()) {
          System.out.println(sc.nextInt()*1000);
          }

          이부분에서 while(sc.hasNextInt())와 while(hasNextInt(sc))의 차이점이 무엇인지 알고 싶습니다.

          둘다 변수에 메소드를 사용하는 방법인거 같은데

          메소드수업에서 메소드의 입력값을 넣을때 괄호 안에 변수의 값을 넣어서 이해가 됬습니다.

          하지만 이번에는 변수뒤에 "."을 넣어서 사용하는게 서로 무슨차이가 있는지 모르겠습니다.

          직접 while(hasnextInt(sc)) 괄호안에 변수를 넣어서 보니 에러가 뜨더군요.
        • 풍운도장
          시즌1을 마치며 차분하고 꼼꼼하고 통찰력 있는 강의 내용에 놀라고, 배려하고 나누는 따뜻한 마음에 더욱 놀랍습니다.
          넘사벽이었던 객체지향의 개념도 강사님과 함께 시간을 "많이" 배정해서 꼭 이해하고 싶습니다.
          감사합니다.
        • 자바초보
          감사합니다!!!
        • 녹두
          최고의 강의였습니다. 시즌1.
        • Yena Hwang
          너무 쉬운 설명 감사합니다!!
        • 이런 고급 강의 컨텐츠를 무료로 이용할 수 있는 세상에 살고있다는 사실리 새삼 놀랍고 감사하네요

          정말 잘 보고있습니다

          재차 감사말씀 전합니다
        • Jung Hwan Sung
          어플을 만들고 싶은데 길이 너무 머네요~
        • 박재원
          와 너무 잘가르켜주셔서 하루만에 다 이해하고 다음과정으로 넘어가요 진짜 감사합니다 진짜 이해하기 쉽게 이야기해주시네요 돈받고 강사하시는건어떠세요?
        • 봄동
          시즌 1 완주하는데 몇 달 걸렸습니다.
          저녁시간에만 쬐금씩 강의를 듣느라 그런지 남들보다 너무 늦네요.
          3일 정도 걸려서 완료하다니....
        • 킹멕스
          최고의 명강의 입니다. 시즌 2 도 열심히 듣겠습니다.
          감사합니다
        • 지나가는학생
          시즌1 완료했습니다. 이전에 C를 했던 경험이 있어 3일 정도 걸려서 완료했습니다.
          시즌2는 이제 저도 처음부터 시작이네요. 열심히 해서 완강하겠습니다!
          좋은강의 올려주셔서 감사합니다
        • 꼼맹
          강의 잘 듣고 있습니다.
          10년 전에 자바프로그래머 이었지만 다른 직종으로 전환했는데
          안드로이드(어플) 개발을 한번 해보려고 자바 강의를 찾다가 생활코딩을 접하게 되었는데 잊고 있었던 것들이 새록새록 기억나게 되네요
          너무나 좋은강의 이고 제가 접해본 어떤 강의보다도 더 훌룡합니다.
          벌써부터 2강 강의가 기다려 지네요 빨리 클릭해야 겠습니다. 감사합니다.
        • 아짱
          드디어 절반이 끝난것인가....ㅎㅎ
          객체 지향은 낼부터 공부를 해야 할거 같습니다.

          강의 너무 잘 되어 있어서 지루하지 않고
          머리에 쏙쏙 들어와서 너무 좋습니다.
        • 유랑유랑
          강의 잘 들었습니다~
          이제 객체지향 들으려하는데...
        • 강의 정말 잘하시는것 같아요

          조금만 더 이걸 일찍 봤더라면 좋았을텐데...
        • jeyul
          우끼끼님, Scanner로 한 줄(문자열)씩 입력 받으려면 hasNextLine(), nextLine() 메소드를 사용해 보세요.
          hasNext(), next() 메소드는 토큰 단위로 하나하나씩 처리되네요.
          대화보기
          • 루베크
            지금 프로그래밍을 공부하면서 가지고 있었던 고민을 정말 적나라게 표현해 주시고 해결책도 주셨습니다.
            짧지만 아이들을 가르쳤던 경험을 봤을때 정말 가르치는 선생님의 정석을 보여주십니다.
            프로그래밍뿐만 아니라 교육은 이렇게 하는 것이다 라는 것까지 배우게 됩니다.
            정말 감사합니다.
          • 우끼끼
            저 숫자로만 무한반복 입력이가능한가요???
            package partice1;

            import java.util.Scanner;

            public class OneRespones {

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

            while(sc.hasNext()){
            System.out.println(sc.next());
            }

            sc.close();

            }

            }
            이걸로하면 으흠... 입력하고 출력하면 나오는데 그다음부터 이상하게나오기나오는데 뭔가 찜찜해서
            문자열로 하는법은 이클립스로 보고 찾아봤는데 맞는지좀... 자바초보라 ㅠㅠ
          • Daivd
            정말 부드러운 말씨로 천천히 & 확실히 설명해주셔서 감사합니다.
            이러한 노력이 결코 헛되지 않도록 시간을 충분히 가지고 열심히 하겠습니다.^^
          버전 관리
          egoing
          현재 버전
          선택 버전
          graphittie 자세히 보기