From c2f1fa87c6f3a3a5875ceb8c5c7288cada06276c Mon Sep 17 00:00:00 2001 From: eunsaem913 Date: Fri, 17 Oct 2025 01:40:30 +0900 Subject: [PATCH 1/9] =?UTF-8?q?docs:=20=EB=A6=AC=EB=93=9C=EB=AF=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd90ef0247..0648e57598 100644 --- a/README.md +++ b/README.md @@ -1 +1,57 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse + +## 과제 진행 요구 사항 +- 문자열 덧셈 계산기 저장소를 포크하고 클론 하는 것으로 시작 +- 기능을 구현하기 전 README.md에 구현할 기능 목록을 정리해 추가 +- Git의 커밋 단위는 앞 단계에서 README.md에 정리한 기능 목록 단위로 추가 + +## 기능 요구 사항 +| 입력한 문자열에서 숫자를 추출하여 더하는 계산기 구현 +- 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. + +`ex) "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6` +- 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. +- 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. + +`ex) "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론이며, 결과 값은 6이 반환되어야 한다.` + +- 사용자가 잘못된 값을 입력할 경우 `IllegalArguemntException`을 발생시킨 후 애플리케이션은 종료되어야 한다. + +## 입출력 요구 사항 +### 입력 +- 구분자와 양수로 구성된 문자열 +### 출력 +- 덧셈 결과 + +`결과 : 6` + +### 실행 결과 예시 + +`덧셈할 문자열을 입력해 주세요.` + +`1,2:3` + +`결과 : 6` + +## 프로그래밍 요구 사항 +- JDK 21 버전에서 실행 가능해야 한다. +- 프로그램 실행의 시작점은 Application의 main() 이다. +- build.gradle 파일은 변경할 수 없으며, 제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다. +- 프로그램 종료 시 `System.exit()`를 호출하지 않는다. +- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다. +- 자바 코드 컨벤션을 지키면서 프로그래밍한다. + +### 라이브러리 +- `camp.nextstep.edu.missionutils`에서 제공하는 Console API를 사용하여 구현해야 한다. +- 사용자가 입력하는 값은 `camp.nextstep.edu.missionutils.Console`의 `readLine()`을 활용한다. + +## 기능 목록 +- 사용자가 문자열을 입력한다. +- 잘못된 값인지 확인한다. +- 잘못된 값(음수, 숫자가 아닌 문자)이라면 IllegalArgumentException 발생 후 종료 +- 커스텀 구분자가 있는지 확인한다. + - 있을 경우 커스텀 구분자를 기준으로 숫자 분리 + - 없을 경우 기본 구분자로 분리 +- 분리된 문자열을 숫자로 변환한다. +- 변환된 숫자를 합한다. +- 합을 반환한다. \ No newline at end of file From 805957d803b193314e1aad20ee6915505688aa7e Mon Sep 17 00:00:00 2001 From: eunsaem913 Date: Sat, 18 Oct 2025 22:44:25 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=B0=9B=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/calculator/Application.java | 1 + src/main/java/calculator/InputView.java | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/main/java/calculator/InputView.java diff --git a/README.md b/README.md index 0648e57598..46be92d212 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ ## 기능 목록 - 사용자가 문자열을 입력한다. - 잘못된 값인지 확인한다. -- 잘못된 값(음수, 숫자가 아닌 문자)이라면 IllegalArgumentException 발생 후 종료 + - 잘못된 값(음수, 숫자가 아닌 문자)이라면 IllegalArgumentException 발생 후 종료 - 커스텀 구분자가 있는지 확인한다. - 있을 경우 커스텀 구분자를 기준으로 숫자 분리 - 없을 경우 기본 구분자로 분리 diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580fb40..3974c577aa 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -3,5 +3,6 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + String input = InputView.readInput(); } } diff --git a/src/main/java/calculator/InputView.java b/src/main/java/calculator/InputView.java new file mode 100644 index 0000000000..a284735275 --- /dev/null +++ b/src/main/java/calculator/InputView.java @@ -0,0 +1,12 @@ +package calculator; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + + public static String readInput() { + System.out.println("덧셈할 문자열을 입력해 주세요."); + String line = Console.readLine(); + return line; + } +} From d27ad44da41515a47e87ca7e4670585bcdae4e3c Mon Sep 17 00:00:00 2001 From: Eunsaem03 Date: Sun, 19 Oct 2025 19:12:52 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20=EA=B5=AC=EB=B6=84=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=EC=9E=90=EB=A5=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 1 + src/main/java/calculator/StringSplitter.java | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/main/java/calculator/StringSplitter.java diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 3974c577aa..95353044ed 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -4,5 +4,6 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 String input = InputView.readInput(); + StringSplitter.splitInput(input); } } diff --git a/src/main/java/calculator/StringSplitter.java b/src/main/java/calculator/StringSplitter.java new file mode 100644 index 0000000000..c852803897 --- /dev/null +++ b/src/main/java/calculator/StringSplitter.java @@ -0,0 +1,13 @@ +package calculator; + +public class StringSplitter { + public static String[] splitInput(String input) { + if (!Character.isDigit(input.charAt(0))) { + String delimiter; + delimiter = String.valueOf(input.charAt(2)); + String customRegex = "[" + delimiter + ",:]"; + return input.split(customRegex); + } + return input.split("[,:]"); + } +} From fc5ba35c43f78b7f224345311a9c42791e996fd0 Mon Sep 17 00:00:00 2001 From: Eunsaem03 Date: Sun, 19 Oct 2025 19:53:56 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20=EC=9E=90=EB=A5=B8=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=EC=9D=84=20=EC=88=AB=EC=9E=90=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 3 ++- src/main/java/calculator/NumberParser.java | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/main/java/calculator/NumberParser.java diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 95353044ed..9d03085616 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -4,6 +4,7 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 String input = InputView.readInput(); - StringSplitter.splitInput(input); + String[] splitInput = StringSplitter.splitInput(input); + int[] numbers = NumberParser.changeNumber(splitInput); } } diff --git a/src/main/java/calculator/NumberParser.java b/src/main/java/calculator/NumberParser.java new file mode 100644 index 0000000000..ab9c3c048e --- /dev/null +++ b/src/main/java/calculator/NumberParser.java @@ -0,0 +1,11 @@ +package calculator; + +public class NumberParser { + public static int[] changeNumber(String[] splitInput) { + int[] numbers = new int[splitInput.length]; + for (int i = 0; i < splitInput.length; i++) { + numbers[i] = Integer.valueOf(splitInput[i]); + } + return numbers; + } +} From 76182f9fddf0e03f93aa41cdf93ea6358c9ff10f Mon Sep 17 00:00:00 2001 From: Eunsaem03 Date: Sun, 19 Oct 2025 20:03:45 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20=EC=88=AB=EC=9E=90=20=ED=95=A9=20?= =?UTF-8?q?=EA=B5=AC=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 1 + src/main/java/calculator/SumCalculator.java | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/main/java/calculator/SumCalculator.java diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 9d03085616..33e30bcd33 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -6,5 +6,6 @@ public static void main(String[] args) { String input = InputView.readInput(); String[] splitInput = StringSplitter.splitInput(input); int[] numbers = NumberParser.changeNumber(splitInput); + int result = SumCalculator.sum(numbers); } } diff --git a/src/main/java/calculator/SumCalculator.java b/src/main/java/calculator/SumCalculator.java new file mode 100644 index 0000000000..c489161cdb --- /dev/null +++ b/src/main/java/calculator/SumCalculator.java @@ -0,0 +1,13 @@ +package calculator; + +public class SumCalculator { + public static int sum (int[] numbers) { + int total = 0; + + for (int number : numbers) { + total += number; + } + + return total; + } +} From be33cecee6f0505504bc30fd2db8b7998cff968e Mon Sep 17 00:00:00 2001 From: Eunsaem03 Date: Sun, 19 Oct 2025 20:23:45 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20=EC=88=AB=EC=9E=90=20=ED=95=A9=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 1 + src/main/java/calculator/OutputView.java | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/main/java/calculator/OutputView.java diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 33e30bcd33..ee8903a0eb 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -7,5 +7,6 @@ public static void main(String[] args) { String[] splitInput = StringSplitter.splitInput(input); int[] numbers = NumberParser.changeNumber(splitInput); int result = SumCalculator.sum(numbers); + OutputView.printResult(result); } } diff --git a/src/main/java/calculator/OutputView.java b/src/main/java/calculator/OutputView.java new file mode 100644 index 0000000000..fe221d755c --- /dev/null +++ b/src/main/java/calculator/OutputView.java @@ -0,0 +1,7 @@ +package calculator; + +public class OutputView { + public static void printResult(int result) { + System.out.println("결과: " + result); + } +} From a392e55d9ed89280ecbf9b772eef73ca5f2f0ee7 Mon Sep 17 00:00:00 2001 From: Eunsaem03 Date: Sun, 19 Oct 2025 23:57:55 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20=ED=97=A4=EB=8D=94=EB=B6=80=EB=B6=84?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/OutputView.java | 2 +- src/main/java/calculator/StringSplitter.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/calculator/OutputView.java b/src/main/java/calculator/OutputView.java index fe221d755c..833953b69e 100644 --- a/src/main/java/calculator/OutputView.java +++ b/src/main/java/calculator/OutputView.java @@ -2,6 +2,6 @@ public class OutputView { public static void printResult(int result) { - System.out.println("결과: " + result); + System.out.println("결과 : " + result); } } diff --git a/src/main/java/calculator/StringSplitter.java b/src/main/java/calculator/StringSplitter.java index c852803897..ceda5d8399 100644 --- a/src/main/java/calculator/StringSplitter.java +++ b/src/main/java/calculator/StringSplitter.java @@ -5,6 +5,7 @@ public static String[] splitInput(String input) { if (!Character.isDigit(input.charAt(0))) { String delimiter; delimiter = String.valueOf(input.charAt(2)); + input = input.replaceAll("^.*\\\\n", ""); String customRegex = "[" + delimiter + ",:]"; return input.split(customRegex); } From 9ead665ca263d549bcbec5471972669fa28e8eed Mon Sep 17 00:00:00 2001 From: Eunsaem03 Date: Mon, 20 Oct 2025 01:31:35 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EA=B0=92=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20IllegalArgumentExc?= =?UTF-8?q?eption=20=EB=B0=9C=EC=83=9D=20=EB=B0=8F=20=EC=A2=85=EB=A3=8C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/calculator/Application.java | 15 ++++++++++----- src/main/java/calculator/NumberParser.java | 3 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index ee8903a0eb..b14d754015 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -3,10 +3,15 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 - String input = InputView.readInput(); - String[] splitInput = StringSplitter.splitInput(input); - int[] numbers = NumberParser.changeNumber(splitInput); - int result = SumCalculator.sum(numbers); - OutputView.printResult(result); + try { + String input = InputView.readInput(); + String[] splitInput = StringSplitter.splitInput(input); + int[] numbers = NumberParser.changeNumber(splitInput); + int result = SumCalculator.sum(numbers); + OutputView.printResult(result); + } catch (IllegalArgumentException e) { + System.out.println("Error " + e.getMessage()); + throw e; + } } } diff --git a/src/main/java/calculator/NumberParser.java b/src/main/java/calculator/NumberParser.java index ab9c3c048e..e2eaa7e992 100644 --- a/src/main/java/calculator/NumberParser.java +++ b/src/main/java/calculator/NumberParser.java @@ -4,6 +4,9 @@ public class NumberParser { public static int[] changeNumber(String[] splitInput) { int[] numbers = new int[splitInput.length]; for (int i = 0; i < splitInput.length; i++) { + if (!splitInput[i].matches("\\d+")) { + throw new IllegalArgumentException("형식을 벗어남"); + } numbers[i] = Integer.valueOf(splitInput[i]); } return numbers; From d1e32c343b1776171775358f09909f3b47c90dee Mon Sep 17 00:00:00 2001 From: Eunsaem03 Date: Mon, 20 Oct 2025 02:29:15 +0900 Subject: [PATCH 9/9] =?UTF-8?q?docs:=20README=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46be92d212..0d4f38f6b7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ - Git의 커밋 단위는 앞 단계에서 README.md에 정리한 기능 목록 단위로 추가 ## 기능 요구 사항 -| 입력한 문자열에서 숫자를 추출하여 더하는 계산기 구현 +> 입력한 문자열에서 숫자를 추출하여 더하는 계산기 구현 - 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. `ex) "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6` @@ -54,4 +54,54 @@ - 없을 경우 기본 구분자로 분리 - 분리된 문자열을 숫자로 변환한다. - 변환된 숫자를 합한다. -- 합을 반환한다. \ No newline at end of file +- 합을 반환한다. + +## 베운 것 +### regex 패키지 클래스 +- Pattern 클래스 + - 문자열을 정규표현식 패턴 객체로 변환해주는 역할 + - 문자열을 정규식 문법에 알맞게 구성해주지 않으면 예외 발생 + - 일반 클래스처럼 공개된 생성자를 제공하지 않아서 정규식 패턴 객체를 생성하려면 compile() 정적 메서드를 호출해야 함 +- Matcher 클래스 + - 대상 문자열의 패턴을 해석하고 주어진 패턴과 일치하는지 판별하고 반환된 필터링된 결과값들을 지니고 있음 + - Patter 클래스와 마찬가지로 공개된 생성자가 없으며, Pattern 객체의 matcher() 메서드를 호출해서 얻음 +### StringTokenizer vs split +- StringTokenizer + - java.util에 포함되어 있는 클래스 + - 문자 또는 문자열로 문자열 구분 + - 빈 문자열을 토큰으로 인식하지 않음 + - 결과 값이 문자열 + - 전체 토큰을 보고싶다면 반복문으로 하나씩 뽑아야 함 +- split + - String 클래스에 속해있는 메서드 + - 정규표현식으로 구분 + - 빈 문자열을 토큰으로 인식 + - 결과값이 문자열 배열 +### Character.isDigit() +- 주어진 문자가 숫자인지 판별 +- 문자가 숫자면 true +### 문자열을 숫자로 변환 +- java.lang.Integer 클래스의 parseInt()와 valueOf() 메서드 사용 가능 + +**Integer.parseInt()** +- 파라미터로 숫자로 변환할 문자열을 입력받고, 입력받은 문자열을 integer로 변환한 int 값을 리턴 +- private type인 int 리턴 + +**integer.valueOf()** +- 문자열을 변환하여 integer Object를 리턴 + +### replace vs replaceAll +- replace: 단순 문자열 `replace(".", "#");` +- replaceAll: 정규식 `replaceAll("\\.", "#");` + - 정규식이어서 이스케이프를 사용하지 않으면 전체로 인식해서 모든 문자가 #으로 대체 + +### IllgalArgumentException +- 메서드에 인수가 잘못된 경우 발생하는 예외 +- 메서드에 전달된 인수가 예상된 형식이나 범위를 벗어나는 경우에 발생 +- 주로 메서드의 파라미터 유효성을 검사하는데 사용 + +**발생 이유** +- 메서드에 전달된 인수의 형식이나 타입이 예상과 다를때 +- 메서드에 전달된 인수가 null이지만 null을 허용하지 않는 경우 +- 메서드에 전달된 인수가 허용되는 범위를 벗어날때 +- 기타 인수의 유효성을 검사하는 조건에 위반될 때 \ No newline at end of file