정말 간단한 문제다.
a + b = (a+b) 를 sysout 하는 것.
나는 그냥 손쉽게 이렇게 했는데,
int c = a + b;
System.out.print(a + " + " + b + " = " + c);
다른 사람들이 쓴 코드는 의외로 다른 점들이 있어서 가져왔다.
1. printf
System.out.printf("%d + %d = %d",a,b,a+b);
println 과 문법이 조금 다르다.
println은 변수값을 변환하지 않고 그대로 출력하지만, printf는 변수값을 변환하여 출력할 수 있다.
System.out.printf("출력 서식", 출력 내용);
줄바꿈을 하려면 지시자 '%n'을 넣어줘야 한다.
출력값의 수만큼 지시자도 사용해야 하며, 출력값과 지시자의 순서와 형식이 일치해야 한다.
출력하려는 값은 콤마(,)로 구분한다.
지시자를 제외한 문자는 입력한 그대로 출력된다.
단일로 쓰이고 결합해서 쓰일 수도 있다.
출력 서식 지시자 | 생략 가능 지시자 | ||
%b | boolean | n | 출력할 전체 자리수 지정 (오른쪽 정렬) ex) %3d |
%d | 정수 | 0 | 전체 자리수가 지정된 경우, 왼쪽에 남는 자리에 0을 출력 ex) %03d |
%o | 8진수 정수 | - | 전체 자리수가 지정된 경우, 왼쪽 정렬하고 빈칸에 공백 출력 |
%x (or %X) | 16진수 정수 | .m | 소수점 아래 자리수 지정. 잘리는 소수점 자리수 반올림. |
%f | 소수점 | ||
%c | 문자 | ||
%s | 문자열 | ||
%n | 줄바꿈 기능 | ||
%e (or %E) | 지수 표현식 |
// 자리수 미지정시 왼쪽 정렬됨
System.out.printf("자리수 미지정 :%d%n", 10); // 자리수 미지정 :10
// 자리수 지정시 오른쪽 정렬되고 남는 자리수는 공백
System.out.printf("자리수 지정 :%4d%n", 10); // 자리수 지정 : 10
// 자리수 지정 후 '-' 사용시 왼쪽 정렬됨
System.out.printf("자리수 지정(-) :%-4d%n", 10); // 자리수 지정(-) :10
// 자리수 지정 후 '0' 사용시 오른쪽 정렬되고 남는 자리수는 0으로 채움
System.out.printf("자리수 지정(0) :%04d%n", 10); // 자리수 지정(0) :0010
float f = 1.1115f;
// 소수점 자리수 미지정
System.out.printf("%f%n",f); // 1.111500
// 소수점 자리수 지정
System.out.printf("%.3f%n",f); // 1.112
여기서 왜 값이 1.1115가 아니라 1.111500이 나오지? 싶어서 찾아봤더니
float은 소수점 7자리까지 나타내기 때문이라고 한다. 오~
그러다가 float과 double을 비교하는 글을 봤는데,
float은 34byte, double은 64byte여서 double이 더 길게 표현할 수 있다, 외에도
정말 재미있는 사실을 발견했다.
바로, 소수점 연산이 아주 이상하고 어렵다는 것~!
float fnum = 0.001f + 0.001f + 0.0001f;
System.out.println(fnum);
// 0.0021000002
double dnum = 0.001 + 0.001 + 0.0001;
System.out.println(dnum);
// 0.0021
float fnumber = 0.01f + 0.001f + 0.0001f;
System.out.println(fnumber);
// 0.0111
double dnumber = 0.01 + 0.001 + 0.0001;
System.out.println(dnumber);
// 0.011099999999999999
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 이게 뭐야.... 이게 ㅋㅋㅋㅋㅋㅋ 이게 뭐야 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
그리구 float은 소수점 7자리까지 나타나야지 왜 0.0111에서 댕겅 잘리냐 일관성좀..
2. 자바 변수와 자료형 (4) float, double
이 포스트에서는 자바 프로그래밍 언어의 기본 자료형인 char, boolean, byte, short, int, long, float, double중에서 실수를 표현 할 수 있는 float, double에 대해 알아보도록 하겠다. 예상 독자자바를 배우고
imasoftwareengineer.tistory.com
자세한 설명은 윗 게시글 참조~
오늘의 교훈 : 소수점 연산은 최대한 피하자~ ^^!
2. BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken()), b = Integer.parseInt(st.nextToken());
System.out.print(a + " + " + b + " = " + (a + b));
BufferedReader는 Scanner와 마찬가지로 값을 입력받을 수 있는 메서드이다.
그러나 둘은 차이점이 많다.
Scanner | BufferedReader | |
입력값 인식 | 띄어쓰기, 개행문자 | 개행문자 |
입력값 타입 | 원하는 타입 바로 입력 | String으로 고정 => 가공작업 필요 |
버퍼 사이즈 | 1024 char => 많은 입력이 필요할 경우 성능이 좋지 못함 |
8192 char => 속도가 빠르다. 입력이 많을 때 유리하다. |
동기화 | X => 멀티쓰레드 환경에서 안전하지 못함 |
O => 멀티쓰레드 환경에서 안전함 |
즉, Scanner로 값을 입력받을 때에는 두가지 방법으로 값을 입력해도 결과값이 같지만
1
2
// 1 + 2 = 3
1 2
// 1 + 2 = 3
BufferedReader로 값을 입력받을 때에는 엔터를 할 경우 NoSuchElementException 오류가 뜬다!
(StringTokenizer는 입력받은 데이터를 후가공처리 하는 것이다. 입력을 따로 두 번 받는 것이 아님)
1
/*
* Exception in thread "main" java.util.NoSuchElementException
* at java.base/java.util.StringTokenizer.nextToken(StringTokenizer.java:347)
* at Algo/Programmers.brbw.main(brbw.java:15)
*/
1 2
// 1 + 2 = 3
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
int i = Integer.parseInt(br.readLine());
}
readLine() 메서드로 입력을 받으며, 그 리턴값은 String으로 고정된다.
따라서 다른 타입으로 입력받고자 한다면 형변환과 예외처리가 반드시 필요하다.
BufferedReader는 개행문자 단위로 데이터를 읽어온다.
만약 이를 띄어쓰기(공백) 단위로 데이터를 가공하고자 한다면 따로 작업을 해주어야 한다.
2-1. StringTokenizer
StringTokenizer는 nextToken() 함수와 함께 쓰이며,
readLine()을 통해 받은 입력값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
}
2-2. String.split()
String.split() 함수는 배열에 공백단위로 끊어 데이터를 저장하여 사용할 수 있다.
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
String arr[] = str.split(" ");
}
BufferdReader 클래스의 메인함수들이다.
함수 | 반환 타입 | |
close() | 입력 스트림을 닫고 사용하던 자원 해제 | void |
mark(int, readAheadLimit) | 스트림의 현재 위치를 마킹 | void |
read() | 한 글자만 읽어 정수형으로 반환 (int)'3' = 51 '3'을 읽어 정수형으로 반환 |
int |
readLine() | 한 줄을 읽음 | String |
ready() | 입력 스트림이 사용할 준비가 되었는지 확인 | boolean (1 = 준비완료) |
3. BufferedWriter
BufferedReader 가 많은 양의 입력이 생길 때 쓴다면,
BufferedWriter 는 많은 양의 출력이 생길 때 쓴다.
즉, 버퍼로 입력을 받았으면 동일하게 버퍼로 출력하는 것이 좋다.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 선언
String str = "hello buffer"; // 출력할 문자열
bw.write(str); // 출력
bw.newLine(); // 줄바꿈 == bw.write("/n");
bw.flush(); // 남아있는 데이터 모두 출력
bw.close();
BufferedWriter 는 System.out.println(); 처럼 출력과 개행을 동시에 해주지 않아서 별도의 코드를 작성해야 한다.
또한, 버퍼 사용 후 반드시 flush()/ close()를 해주어야 한다.
close()는 출력스트림을 아예 닫아버리기 때문에, 다른 것도 출력하고자 하면 flush()를 사용하면 된다.
write() 함수는 세 가지 방법으로 사용할 수 있다.
write(int c)
=> 한 글자 쓰기
write(char[] buf, int offset, int length)
=> char[]를 offset 위치부터 length 크기만큼 출력
write(String s, int offset, int length)
=> 문자열을 offset 위치부터 length 크기만큼 출력
위의 풀이 코드를 변형해보자면 아래와 같이 쓸 수 있다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken()), b = Integer.parseInt(st.nextToken());
br.close(); // 입력 스트림 닫기
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 출력스트림 열기
bw.write(a + " + " + b + " = " + (a + b));
bw.close();
[Java 10] 자바의 출력문(println, printf)
No. 01 출력 - println() 개발자가 열심히 프로그래밍을 하더라도 결과를 볼 수 있는 명령문을 실행하지 않으면 절대 직접 눈으로 볼 수 없다. 결과를 봐야 이 프로그램이 내가 생각한대로 잘 돌아가
keep-cool.tistory.com
[Java] 빠른 입출력을 위한 BufferedReader, BufferedWriter, StringTokenizer, StringBuilder
BufferedReader / BufferedWriter BufferedReader와 BufferdWriter는 버퍼를 사용하여 읽기와 쓰기를 하는 함수이다. 버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달된다.
rlakuku-program.tistory.com