diff --git a/README.md b/README.md index bd90ef0247..c6d2cdd9dd 100644 --- a/README.md +++ b/README.md @@ -1 +1,46 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse +<과제 진행 요구사항> +1. 포크 및 클론으로 시작 +2. README에 구현할 기능 목록을 정리해가면서 추가한다. +3. 커밋 규칙에 따라 메시지 작성한다. + +<기능 요구 사항> +1. 쉼표 또는 콜론을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. +2. 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. +3. 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다. => 예외 발생시키기 + +- 입력: 구분자와 양수로 구성된 문자열 + +- 출력: +덧셈 결과 : 6 +덧셈할 문자열을 입력해 주세요. +1,2:3 +결과 : 6 + +<프로그래밍 요구 사항> +- JDK는 21버전 +- Application의 메인에서 시작 +- build.gradle 수정 불가 및 제공된 라이브러리 제외한 외부 라이브러리 사용금지 +- 프로그램 종료시 System.exit() 호출 금지 +- 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다.(요구사항에서 명시가 되었다면 가능) +- 코드 컨벤션을 지키면서 프로그래밍 한다. = Java Style Guide를 원칙 +---------------------------------------------------------------- +<기능 구현 전 생각해보기> +1.의사 코드 작성하기 +- 입력을 받는다. = camp.nextstep.edu.missionutils.Console의 readLine()을 활용한다. // 구분자와 양수로 구성된 문자열 +- 계산기 기능을 구분한다. +- 값을 담을 변수를 선언 및 초기화를 한다. + +2. 기능 구현하기 +- 빈 문자열 입력 시 0을 반환한다. +- 쉼표와 콜론으로 구분된 숫자들을 더한다. +- 커스텀 구분자를 지정할 수 있다. +- 숫자가 아닌 값이 들어오면 예외를 발생시킨다. +- 결과를 "결과(변수) : n"형태로 출력한다. + +3. 예외처리 순서 +- 1. //로 시작하지만 \n이 없을 경우 +- 2. //와 \n 사이에 빈 문자열이거나 공백이 있을 경우 +- 3. 토큰화 결과 빈 토큰일 경우 +- 4. //와 \n 사이에 양수가 아닌 0 또는 음수가 들어올 경우 +- 5. //와 \n 사이에 숫자 외에 문자가 들어올 경우 diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580fb40..84f663e0fe 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,60 @@ package calculator; +import java.util.regex.Pattern; +import camp.nextstep.edu.missionutils.Console; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + System.out.println("덧셈할 문자열을 입력해 주세요."); + String input = Console.readLine(); + + if (input == null || input.isEmpty()) { + System.out.println("결과 : 0"); + return; + } + + String[] tokens; + + if (input.startsWith("//")) { + int newLineIndex = input.indexOf("\n"); + + String customDelimiter; + String numbers; + + if (newLineIndex >= 0) { + customDelimiter = input.substring(2, newLineIndex); + numbers = input.substring(newLineIndex + 1); + } else { + customDelimiter = input.substring(2); + String secondLine = Console.readLine(); + if (secondLine == null) throw new IllegalArgumentException(); + numbers = secondLine; + } + + if (customDelimiter.isEmpty() || customDelimiter.isBlank()) throw new IllegalArgumentException(); + if (customDelimiter.matches("-?\\d+")) throw new IllegalArgumentException(); + + tokens = numbers.split(Pattern.quote(customDelimiter), -1); + } else { + tokens = input.split("[,:]", -1); + } + + int sum = 0; + for (String raw : tokens) { + if (raw == null) throw new IllegalArgumentException(); + String token = raw.trim(); + if (token.isEmpty()) throw new IllegalArgumentException(); + + final int number; + try { + number = Integer.parseInt(token); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(); + } + if (number <= 0) throw new IllegalArgumentException(); + + sum += number; + } + System.out.println("결과 : " + sum); } } diff --git a/src/test/java/calculator/ApplicationTest.java b/src/test/java/calculator/ApplicationTest.java index 93771fb011..1e64cc201f 100644 --- a/src/test/java/calculator/ApplicationTest.java +++ b/src/test/java/calculator/ApplicationTest.java @@ -8,10 +8,11 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; class ApplicationTest extends NsTest { + @Test void 커스텀_구분자_사용() { assertSimpleTest(() -> { - run("//;\\n1"); + run("//;\n1"); assertThat(output()).contains("결과 : 1"); }); }