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. 호두
    잊어버렸거나, 완전히 내것이 되었거나.
  2. 닷미
    학원보다 훨씬 나아요 ㅠㅠ
  3. j-graphy
    2019. 2. 2. 학습완료
  4. j-graphy
    Scanner sc = new Scanner(System.in);
    while(sc.hasNextInt()) {
    System.out.println(sc.nextInt()*1000);
    }
    sc.close();

    while이 참이여서 반복되면 System.out.println(sc.nextInt()*1000); 이부분만 계속반복되는 것이여야 하는 것 아닙니까?

    그러면 입력값이2이라 했을때 2000이 하면에 계속 반복해서 나와야 하는데 왜다시 입력값을 받을수 있게 되는지 설명좀 해주새요 부탁드립니다.

    이미 5개월 전 댓글이라 이해가 완전히 되셨을지 모르겠지만, 제 자신의 이해를 돕기 위해서 저 또한 댓글을 남깁니다.
    while문 안에 있는 hasNextInt()라는 메서드는 sc라는 객체에서 가지고 있냐? 다음에 int를 이라는 것입니다. 즉, sc가 다음에 입력 받을 값이 int냐 아니야를 묻게 되는거죠. 즉, 여기서 int를 받아야만 true가 반환되는 겁니다.
    하지만 여기서 반환되는 값은 입력한 int 값이 아닌 boolean 타입의 데이터(true or false)이죠. 즉, 사용자가 입력한 int 값은 어떻게 받느냐 바로 nextInt라는 메서드를 통해서입니다.
    그러니 사용자가 입력한 값이 int 데이터형이었을 경우(hasNextInt()가 참일 경우) 반복문은 실행되고, 사용자가 입력한 정수(nextInt)에 1000을 곱한 값을 출력하고 다시 처음으로 돌아가 while문에 걸린 조건이 참인지를 보게 되는거죠.

    그럼 여기서 다시 hasNextInt에 걸리게 되니, 대기 상태에 들어가게 되고(사용자가 값을 입력하지 않았기 떄문에), 사용자가 입력할 값이 int인지를 판단하는 상태에 들어가게 되는 것입니다. 헷갈리는 지점이 nextInt가 입력받은 값을 반환하기 때문이라고 생각하는데 hasNextInt는 입력한 값의 데이터 타입이 무엇인지에 관심이 있고, 그 값으로 실제적인 무엇을 하지 않습니다. 그러니 입력받은 값의 데이터 타입만 확인하고 맞다 아니다로만 반환하는거 뿐이죠. 그리고 실제적으로 그걸 가지고 오는 메서드가 NextInt가 되는 것이구요.

    이상 제 소견이었습니다. 혹시라도 제 답변에 이상한 부분이 있으면 비판해주시면 감사하겠습니다
    대화보기
    • 웅이
      2/6 강의 첫번째 예제
      package org.opentutorials.javatutorials.io;

      class InputDemo{
      public static void main(String[] args){
      System.out.println(args.length);
      }
      }
      에서,
      main메소드앞에 void가 있는것은 '출력값'이 없다는 뜻이라고 하셨는데,
      System.out.println(args.length); 는 값을 출력하는 코드이지 않습니까?
      '출력값'이 '반환값'과 다른뜻이라면 void는 해당 메소드안에 '반환값' , 즉 return이 없을때만 쓰이는 것이고,
      '출력값'이 '반환값'과 같은뜻이라면 System.out.println(args.length);이 있을 때는 void를 쓰면 안되는 것 같은데
      전자로 이해 하는것이 맞나요?
    • 예로니
      2019.01.16-시즌1 완료
    • 저도 그게 잘....
      자세히는 답변 드리기 어렵지만 sc라는 이름의 스캐너가 file라는 이름의 파일(객체)을 들여나 보게 되는데요.

      스캐너(Scanner) 객체의 인스턴스(sc)가 가진 메소드가 여기선 hasNextInt 와 nextInt 두가지입니다.
      hasNextInt 파일 내용 첫부분 부터 시작해서 다음 칸에 숫자가 들어있는지를 참 거짓으로 알려주는 메소드입니다.
      그리고 nextInt는 그 숫자가 얼마인지를 알려주는 메소드인데 이름의 'next'라는 의미처럼 스캐너가 다음으로 한 칸 이동해서 그 숫자를 읽어오게 됩니다.
      이게 반복 되면 스캐너가 한칸씩 파일을 쭉 읽어가면서 다음 칸에 숫자가 나오지 않을 때 hasNextInt가 false값을 반환하고 while 루프가 끝나게 되죠.

      조금 더 궁금하신 분들은 포인터와 입출력 스트림에 대해 알아보시면 재미있을 겁니다 :)
    • IT에재능이없는놈
      이 온라인 강의가 없었으면 예전에 국비지원 프로그램 IT 강의 못따라가고 포기했을 거에요...
      초보자도 알아듣기 쉬운 친절한 강의 정말 감사드리고, 새해 복 많이 받으세요~
    • 김요셉
      ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ너무공감입니다
      대화보기
      • 몽몽이
        이것은 둘 중의 하나다. 잊어버렸거나, 완전히 내것이 되었거나.
        크~명언입니다.
      • 광길
        이고잉님 진심 저희 학교 교수님으로 초빙하고 싶습니다... 항상 감사합니다
      • 임효석
        sc.hasnextint() 가 계속해서 true or false를 묻게 하는게 아닐까요? while문 안에서 계속해서 참/거짓인지 판단하는데 그걸 sc.hasnextint()함수가..
        대화보기
        • 항상고맙습니다
          학원에서 자바 배우고있는데 학원선생님보다 대략 2만배정도 더 잘알려 주십니다
        • 감사
          너무 감사합니다
        • Daydream
          여러번보면서 공부하고있습니다.
          늘 감사드립니다.
          20181005
        • 전민희
          2018.10.02 시즌1 완료
        • 항상 감사합니다.
        • 1.4278003733539633
          sc.hasNextInt()
          이 메소드가 입력값을 받습니다
          Scanner sc = new Scanner(System.in);
          이 코드는 sc.hasNextInt()의 sc를 만들어줄 뿐입니다
          대화보기
          • 1.8318794595655508
            굳굳
          • ㅇㅇ
            while문은 괄호안의 조건이 한번 true이면 내용을 무한히 반복실행하는것이 아니라 조건을 검토후 true이면
            실행문을 실행완료한 후 다시 조건을 검토하게됩니다. 그리고 또 조건이 true이면 또 반복 다시 검토를 반복
            하게되는거에요.
            입력값을 2를 넣으면 2000을 화면에 출력 하고 다시 조건을 검토하러 가는데, 조건의 메소드로 인해
            다시 값을 입력할 수 있는 거에요
            대화보기
            • ㅇㅇ
              nextInt 와 hasNextInt() 메소드가 기능이 다릅니다. nextInt는 그 값을 받아 저장하는 기능이고
              hasNextInt()는 들어온값이 Int 정수형이면 true를 반환하고 다른 데이터타입이면 false를 반환하는 기능을
              하는 것 같습니다. while문의 ( )안에는 조건에 true나 false가 들어가야하기 때문에 후자를 사용한것같네요
              대화보기
              • 이지선
                2018.09.04 완료
                이전에 C언어와 자바를 공부한 적이 있었지만 처음 코딩을 배운다는 생각으로 듣고 있습니다. 항상 이 문법을 왜 써야하는 지를 함께 알려주셔서 이해하는데 도움이되네요^^
                객체지향 부분은 더 어려워질 것 같지만 끝까지 노력해보겠습니다! 좋은 강의 만들어주셔서 감사해요~
              • 이해시켜 주새요
                Scanner sc = new Scanner(System.in);
                while(sc.hasNextInt()) {
                System.out.println(sc.nextInt()*1000);
                }
                sc.close();

                while이 참이여서 반복되면 System.out.println(sc.nextInt()*1000); 이부분만 계속반복되는 것이여야 하는 것 아닙니까?

                그러면 입력값이2이라 했을때 2000이 하면에 계속 반복해서 나와야 하는데 왜다시 입력값을 받을수 있게 되는지 설명좀 해주새요 부탁드립니다.
              • 전민희
                갈수록 어렵지만 이해하도록 노력해봐야겠네요. 완료!
              • 오승룡
                궁금한게 있는데,,

                앱이 실행 중 입력방법에서
                int i = sc.nextInt(); 는 이해가 가는데요..

                한번이 아닌 여러번 반복입력이 가능한 입력방법에서
                while(sc.hasnextInt()){ 에서 hasnextInt가 뭔지 모르겠어요.. 왜 여기는 nextInt()가 아닌걸까요..?
              • 오승룡
                cmd에서 띄어쓰기는 인자의 개수를 의미합니다. 즉, 1 2 3은 3개의 인자이지만, 123은 1개의 인자를 나타내죠.

                그래서, 1 2 3은 3을, 123은 1을 출력하는 것입니당!
                대화보기
                • 완료
                • 강현욱
                  씨즌 1 마뭄으리리리릴리!
                • 나해리
                  자바가 아예 처음인데 너무 잘듣고있어요 이전에 C와 C++을 배운 사람이긴 하지만요. 아예 프로그래밍을 처음 배우는 분들 입장에서는 이건 다음에 배운다라고 하고 넘어가시면 답답함을 느끼실 수 있어요. 하지만 넘어가는 데에는 다 이유가 있다고 생각해요 넘어간다고 당장 배우는 내용에 부족함이 있는 것도 아니구요. 오히려 알게 되면 더 헷갈릴만한 것들을 넘어가시는데.. 도서관에서 자바 입문서 두권을 빌려서 읽는데 자세한건 좋지만 이 강의처럼 술술 읽혀지지는 않더라구요. 세상에 자바 교육자료는 많으니 각자 원하는 공부 방식을 택하시면 될 것 같아요. 악플은 달리지 않았으면 좋겠네요ㅠ
                • 이상훈
                  감사합니다
                • 멀캠A_Son
                  완료
                • 이태호
                  6/29
                • 감사합니다
                • 악플러
                  피드백이 아니라 악플이네.
                  당신같은 사람은 이 동영상을 볼 자격이 없다.
                  대화보기
                  • 김현태
                    시즌 1 완료
                  • 4월 30일 입력과 출력 시즌1 완료!
                  • 자바 오프라인 수업 듣고나서 보충용으로 강의보고있는데
                    중간중간 들었던 의문점들을 잘짚어주시네요 언제나 감사합니다!
                  • 박현모
                    감사합니다~
                  • 우주최강옥수수
                    180421 시즌1 이상
                  • ㅠㅠㅜㅜㅜ
                    180413 시즌 1 완료
                  • ㅇㅇ
                    CMD 어려워요 ㅠㅜㅠㅜㅠㅜㅠㅜㅠㅜㅠㅜㅠㅜㅠㅜㅠㅜ
                  • 3/6 수업에서 cmd입력할때 1 하면 1 나오고 1 2 하면 2 나오잖아요
                    근데 띄어쓰기 안하고 1232이렇게 쓰면 왜 그냥 1로 나오는건가요? 사소하지만 궁금해서...띄어쓰기 무슨 의미쥬..그냥 데이터하나로 인식하는거겠죠
                  • 김세창
                    20180402 시즌 1 끝
                  • 김인철
                    180328 수 끝
                  • 박형준
                    180323
                    시즌1 끝
                  • 김예슬
                    180319
                    입력과 출력
                  • 배성재
                    17Mar2018 완료
                  • egoing
                    수정했습니다. 고맙습니다 :)
                    대화보기
                    • 불곰
                      강의 잘들었습니다 이고잉님!

                      보다보니
                      시즌1을 마치며에
                      '휼룡한'
                      이런 오타가 있네요 ^^
                    • 컴샘
                      package method;

                      import java.util.Scanner;

                      public class scanneer2{

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

                      }

                      }

                      이 코드가 에러가 나는데요. 이유가 무엇일까요?
                    버전 관리
                    egoing
                    현재 버전
                    선택 버전
                    graphittie 자세히 보기