Java

[Java] 타입 변환, 입력 스트림, Scanner, 원의 넓이 구하기

ruming 2021. 10. 16. 21:21

*명품자바프로그래밍 2장*

자동 타입 변환

- 작은 타입은 큰 타입으로 자동 변환 (컴파일러에 의해)

- 치환문이나 수식 내에서 타입이 일치하지 않을 때

long m = 25;   //25가 long 타입으로 자동 변환
double d = 3.14 * 10;    //10이 10.0으로 자동 변환

 

강제 타입 변환

- 큰 타입이 작은 타입으로 변환할 때 : 자동 타입 변환이 안 됨

int n = 300;
byte b = n;    //컴파일 오류 byte b = (byte)n;으로 변환 가능

 

- 개발자가 필요하여 강제로 타입 변환 지시

- 값 손실 우려

double d = 1.9;
int n = (int)d;   //n=1  (0.9 손실)

 

System.in

- 키보드로부터 직접 읽는 자바의 표준 입력 스트림

- 키 값을 바이트로 리턴(응용프로그램이 문자 정보로 변환해야 함)

 

 

Scanner 클래스

- System.in에게 키를 읽게 하고, 원하는 타입으로 변환하여 리턴

- java.util.Scanner 클래스

 

객체 생성

import java.util.Scanner;   //import문 필요
...
Scanner a = new Scanner(System.in);    //Scanner 객체 생성

 

- 입력되는 키 값을 공백으로 구분되는 토큰 단위로 읽음

\t, \f, \r, \n, ' '
Scanner scanner = new Scanner(System.in);

String name = scanner.next(); // "Kim"
String city = scanner.next(); // "Seoul"
int age = scanner.nextInt(); // 20
double weight = scanner.nextDouble(); // 65.1
boolean single = scanner.nextBoolean(); // true

 

Scanner 주요 메소드

메소드 설명
String next() 다음 토큰을 문자열로 리턴
byte nextByte() 다음 토큰을 byte 타입으로 리턴
short nextShort() 다음 토큰을 short 타입으로 리턴
int nextInt() 다음 토큰을 int 타입으로 리턴
long nextLong() 다음 토큰을 long 타입으로 리턴
float nextFloat() 다음 토큰을 float 타입으로 리턴
double nextDouble() 다음 토큰을 double 타입으로 리턴
boolean nextBoolean() 다음 토큰을 boolean 타입으로 리턴
String nextLine() '\n'을 포함하는 한 라인을 읽고 '\n'을 버린 나머지 문자열 리턴
void close() Scanner의 사용 종료
boolean hasNext() 현재 입력된 토큰이 있으면 true, 아니면 입력 때까지 무한정 대기.
새로운 입력이 들어올 때 true 리턴.
ctrl+z키가 입력되는 입력 끝이므로 false 리턴

 

[원의 면적을 구하는 프로그램] (예제2-2)

public class CircleArea {

	public static void main(String[] args) {
		final double PI = 3.14; // 원주율을 상수로 선언
		
		double radius = 10.0; // 원의 반지름
		double circleArea = radius*radius*PI; // 원의 면적 계산
		
	// 원의 면적을 화면에 출력한다.
		System.out.println("원의 면적 = " + circleArea);
	}

}

원의 면적 = 314.0

 

 

[새로 작성한 코드]

import java.util.Scanner;

public class HelloJava { 
	public static double circleArea(int radius) {
		final double PI = 3.14;		//상수로 PI 선언
		return (double)(PI*radius*radius);	//double로 캐스팅, 원의 넓이 구해서 반환
	}
	public static void main(String[] args) { 
		Scanner scan = new Scanner(System.in);	//스캐너 객체 생성
		System.out.print("반지름 길이 입력 >> ");	
		int radius = scan.nextInt();	//반지름 입력 받음
		double circle = circleArea(radius);		//circleArea로 얻은 원의 넓이 circle 변수에 저장
		System.out.println("원의 넓이 : " + circle);	//원의 넓이 출력
	}
}

반지름 길이를 입력 받고 원의 넓이를 출력해주는 프로그램.

circleArea 함수는 파라미터로 받은 반지름과 상수 PI로 원의 넓이를 구해 반환한다.

반지름은 int형으로 입력받고 계산은 double형으로 함. circleArea함수에서 캐스팅 안해줘도 알아서 변환되는 것 같다.

 

실행결과

 

[예제 2-4 : Scanner를 이용한 키 입력 연습]

import java.util.Scanner;

public class HelloJava { 
	public static void main(String[] args) { 
		Scanner scan = new Scanner(System.in);
		System.out.println("이름, 도시, 나이, 체중, 독신 여부를 빈칸으로 분리하여 입력하세요.");
		
		String name = scan.next();
		String city = scan.next();
		int age = scan.nextInt();
		double weight = scan.nextDouble();
		boolean single = scan.nextBoolean();
		
		System.out.println("이름은 " + name + ", 도시는 " + city + ", 나이는 " + age + ", 체중은 " + weight + ", 독신 여부는 " + single + "입니다.");
	}
}

이름, 도시, 나이, 체중, 독신 여부를 입력 받고 출력하는 프로그램

각 단어에 맞는 타입으로 변수를 선언해 입력받는다.

마지막에 한번에 출력해주었다.

 

실행 결과

 

next()와 nextLine()의 차이

Scanner를 사용하면서 가장 헷갈렸던 부분이다. 

next()는 공백을 기준으로 입력을 받고, nextLIne()은 개행문자를 기준으로 입력을 받는다.

 

next()와 nextLine()을 둘 다 사용할 때 오류가 발생하는 경우가 있다.

버퍼에 \n이 남아있는 경우를 주의해야 한다.

import java.util.Scanner;

public class HelloJava { 
	public static void main(String[] args) { 
		Scanner scan = new Scanner(System.in);
		System.out.println("이름과 도시를 입력하세요.");
		String name = scan.next();
		String city = scan.nextLine();
		System.out.println(name + city);
	}
}

위 코드를 실행해서 입력해보면 다음과 같은 결과가 나온다.

이름을 입력하고 엔터를 치면 도시를 입력할 새 없이 이름이 출력된다.

이름을 next()로 입력받았기 때문에 ruming을 입력받고 엔터를 치면 개행문자(\n)가 버퍼에 그대로 남아있게 된다. next()는 개행문자를 처리하지 않는다. 그래서 nextLint()에 개행문자가 들어가 입력이 끝난 것이다.

 

이 경우 둘 다 nextLine()으로 받거나 중간에 nextLine()을 집어넣어 개행문자를 제거해야한다.

import java.util.Scanner;

public class HelloJava { 
	public static void main(String[] args) { 
		Scanner scan = new Scanner(System.in);
		System.out.println("이름과 도시를 입력하세요.");
		String name = scan.nextLine();	//nextLine()으로 입력
		String city = scan.nextLine();	//nextLine()으로 입력
		System.out.println(name + city);
	}
}

 

import java.util.Scanner;

public class HelloJava { 
	public static void main(String[] args) { 
		Scanner scan = new Scanner(System.in);
		System.out.println("이름과 도시를 입력하세요.");
		String name = scan.next();
		scan.nextLine();	//개행문자 제거
		String city = scan.nextLine();
		System.out.println(name + city);
	}
}

 

엔터로 입력받지 않은 경우

더보기
import java.util.Scanner;

public class HelloJava { 
	public static void main(String[] args) { 
		Scanner scan = new Scanner(System.in);
		System.out.println("이름과 도시를 입력하세요.");
		String name = scan.next();
		String city = scan.nextLine();
		System.out.println(name + city);
	}
}

 여기서 엔터로 입력받지 않고 공백으로 이름과 도시를 입력받으면 어떻게 될까?

 next()로 입력받은 ruming이 출력되고, nextLine()이 공백과 city를 입력받아 출력한다.

 

 

 

 

참고

next() nextline() 차이점