-
TIL #7 - 각종 출력, 입력, 조회 기능프로그래밍/TIL(국비과정) 2020. 4. 2. 19:04
해외와 한국을 나누어서 코로나 관련 정보를 입력, 출력, 조회, 수정, 삭제를 한다.
배열을 이런 식으로 사용한다는 것에 감이 조금은 온 것 같다..
여기서 만들 클래스는 총 5개이다.
Nation.java : 세계 현황에서 쓸 데이터타입을 미리 구현해 놓은 구조체 클래스
City.java : 한국 현황에서 쓸 데이터타입을 미리 구현해 놓은 구조체 클래스
NationUtil.java : 세계 현황에 대해 입력, 출력, 조회, 수정, 삭제 등의 메소드를 모아놓은 클래스
CityUtil.java : 한국 현황에 대해 입력, 출력, 조회, 수정, 삭제 등의 메소드를 모아놓은 클래스
CoronaEx.java : 사용자로부터 기능을 보여주고 사용자로부터 받은 요구들을 수행하고 최종적으로 결과값을 출력하는 메소드
Nation.java
먼저 세계 현황에서 쓸 데이터타입을 미리 구현해 놓은 구조체 클래스를 사용한다.
public class Nation { public String name; // 나라이름 public int confirmed; // 확진자 public int death; // 사망자 public int cured; // 완치자 public int population; // 인구수 }
원래는 국가번호로 국가를 식별하면 좋겠지만, 아직 데이터베이스에 대해서 배우지 않은 상태라 PK와 같은 식별자를 사용할 레벨이 아니므로 기본적인 필드들로 구성했다.
City.java
그 다음은 마찬가지로 국내 현황에서 쓸 데이터 타입들의 구조체 클래스이다.
국내는 해외와는 다르게 격리해제 파트를 추가했다.
package coronaProject; public class City { public String name; // 지역이름 public int confirmed; // 확진자 public int death; // 사망자 public int cleared; // 완치자 public int population; // 인구수 public int endQuarantine; //격리해제 }
CityUtil.java
해외 현황에 대한 각종 기능들이다.
프로그램의 구조는 아래와 같다.
더보기1. 세계 현황
1) 입력하기
(1) 전체수정
(2) 개별수정
2) 출력하기
3) 뒤로
2. 한국현황
1) 입력하기
(1) 전체수정
(2) 개별수정
2) 출력하기
3) 뒤로
3. 종료
사실 NationUtil.java와 CityUtil.java는 거의 흡사하다. 필드만 조금 추가 되었을 뿐 다른 것이 없기 때문에
CityUtil.java 만 보도록 한다.
1. start 메소드
사용자로부터 정보를 입력받는다.
public static City[] start(Scanner scan) { System.out.print("입력할 지역 수 : "); int size = MyScanner.nextInt(scan); City[] cities = new City[size]; for (int i = 1; i < cities.length; i++) { City c = new City(); System.out.print("지역명 : "); c.name = scan.nextLine(); System.out.print("확진자 수 : "); c.confirmed = MyScanner.nextInt(scan); System.out.print("사망자 수 : "); c.death = MyScanner.nextInt(scan); System.out.print("완치자 수 : "); c.cleared = MyScanner.nextInt(scan); System.out.print("격리해제자 수 : "); c.endQuarantine = MyScanner.nextInt(scan); System.out.print("총인구수 : "); c.population = MyScanner.nextInt(scan); System.out.println("--------------------------"); cities[i] = c; } return cities; }
입력받을 지역 수를 사용자로부터 받아 size 변수에 넣는다.
그 size 값은 곧 Cities 배열의 크기가 된다.
그런 후 for문으로 들어가 사용자로부터 입력받은 만큼의 Cities 배열 길이 동안
지역명, 확진자 수, 사망자 수, 완치자 수, 격리해제자 수, 총인구수를 입력받는다.
그런 다음 입력받은 값들을 cities의 배열에 넣는다.
마지막으로 cities를 리턴한다.
(MyScanner는 앞에서 만든 입력과 함께 버퍼메모리를 지워주는 클래스다)
2. print 메소드
입력받은 값들을 출력한다.
public static void print(City[] cities) { if (cities == null) { System.out.println("아직 입력된 정보가 없습니다"); } else { System.out.println("======================================================"); for (int i = 0; i < cities.length; i++) { System.out.print((i + 1)); System.out.print("\t" + cities[i].name); System.out.print("\t" + cities[i].confirmed); System.out.print("\t" + cities[i].death); System.out.print("\t" + cities[i].cleared); System.out.print("\t" + cities[i].endQuarantine); System.out.print(showStat(cities[i])); System.out.println("\t" + cities[i].population); } System.out.println("======================================================"); } }
출력을 할 때에는 먼저 cities 배열이 null 값인지 아닌지 확인한다.
만약 null 일 경우엔 정보가 없다는 메세지를 띄운다.
null이 아닐 경우에는 cities 배열의 길이만큼 cities 배열을 차례로 호출해 입력받은 값들을 출력한다.
중간에 showStat는 바로 뒤에서 할 각종 통계치를 계산하는 메소드이다.
3. showStat 메소드
통계치를 계산한다.
사망률, 완치율, 감염률을 보여준다.
public static String showStat(City c) { double deathRate = (double) c.death / c.confirmed * 100; // 퍼센트니까 * 100 double cureRate = (double) c.cleared / c.confirmed * 100; int ppp = (int) (((double) c.confirmed / c.population) * 1000000); // 어떤 숫자가 있으면 ##.## 형태로 해준다. String result = "\t" + new DecimalFormat("##.##").format(deathRate) + "%\t" + new DecimalFormat("##.##").format(cureRate) + "%\t" + ppp + "%"; return result; }
4. update 메소드
값을 수정하는 메소드이다.
public static City[] update(int index, Scanner scan, City[] cities) { City c = new City(); System.out.print("지역 이름 : "); c.name = scan.nextLine(); System.out.print("확진자 수 : "); c.confirmed = MyScanner.nextInt(scan); System.out.print("사망자 수 : "); c.death = MyScanner.nextInt(scan); System.out.print("완치자 수 : "); c.cleared = MyScanner.nextInt(scan); System.out.print("격리해제자 수 : "); c.endQuarantine = MyScanner.nextInt(scan); System.out.print("총인구수 : "); c.population = MyScanner.nextInt(scan); cities[index] = c; return cities; }
먼저 사용자로부터 수정하고자 하는 index를 받아와 수정을 진행한다.
입력이 끝나면 사용자로부터 받은 배열의 index에 값들을 넣는 걸로 마무리 된다.
CoronaEx.java
사용자에게 요구를 받아 수행하는 클래스이다.
앞에서 잘 만들어 놓은 메소드들을 잘 쓰기만 하면 된다.
다만 if문이 많이 나오기 때문에 길을 잃기 쉽다..
아래의 코드는 모두 메인 메소드 안에서 이뤄지는 코드들이다.
Nation[] world = null; City[] cities = null;
먼저 두 배열을 null 상태로 만들어 정보를 입력받을 준비를 해놓는다.
그런 다음 while문을 돌려 아래의 코드들이 수행되게 한다.
사용자에게 가장 먼저 물어볼 것은 어떤 현황을 볼지 이다.
1. 세계 현황보기 2. 한국 현황보기 3. 종료
위의 옵션이 먼저 나온다.
System.out.println("==== 코로나 상황판 ===="); System.out.println("1. 세계현황 2. 한국현황 3. 종료"); System.out.print(">>");
1. 세계현황으로 먼저 가본다.
세계현황으로 들어간 후에는 세계현황에서 어떤 작업을 수행할지도 물어야한다.
그전에 먼저 세계 현황의 배열인 world가 null인지 아닌지 확인하고 null이면 곧장 입력할 수 있도록
입력 메소드를 호출한다.
if (world == null) { // 비어 있으면 입력하는 메소드 world = NationUtil.start(scan);
null이 아니면 1. 전체 다시 수정 2. 개별 수정 옵션을 보여준다.
} else { System.out.println("1. 전체 다시 수정 2. 개별수정"); System.out.print(">>>>"); choice = MyScanner.nextInt(scan); // update 메소드 if (choice == 1) { // 전체 다시 수정 world = NationUtil.start(scan); } else { // 개별 수정 // 현재 상태 전체를 출력하고 // 수정할 나라의 번호 선택 NationUtil.print(world); System.out.print("수정할 번호를 입력하세요 : "); // 번호 수정하는 인덱스 만듦 int index = validateIndex(scan, world.length); // index에 적합한 숫자를 입력받으면 update 메소드 실행 world = NationUtil.update(world, index, scan); } }
전체 다시 수정일 경우엔 위와 마찬가지로 전체 입력하는 start 메소드를 호출한다.
개별 수정일 경우엔 수정할 번호를 입력받는다.
validateIndex 메소드는 적합한 번호가 나올 때까지 번호 수정을 하게 하는 메소드이다.
만약 내가 1. 서울 2. 부산 정보만 가지고 있는데
3번 인덱스를 수정하겠다고 하면 작업을 계속 수행할 수 없을 것이다.
그런 경우를 방지하기 위해 만든 메소드이다.
public static int validateIndex(Scanner scan, int length) { System.out.print("수정할 번호를 입력하세요 : "); int index = MyScanner.nextInt(scan) - 1; // i+1로 출력을 임의로 만들었기 때문에 (index값이 0부터 시작해서 출력되면 보기에 안좋으니까..) // 그래서 우리가 입력을 받을 때 사용자 입력 숫자 -1 을 해서 프로그램에 넣는다. while (index < 0 || index >= length) { System.out.println("잘못 입력하셨습니다."); System.out.println("수정할 번호를 입력하세요. "); index = MyScanner.nextInt(scan) - 1; // 여기도 마찬가지로 -1 해주어야한다. // 아니면 1을 수정하라고 했는데 // 보이는건 1번 인덱스(사용자 상의)인데 실제 인덱스인 0(프로그램상의)도 역시 수정이 된다. } return index; }
위의 메소드에서 사용자로부터 입력받은 index에서 -1를 하는 이유는,
Util 클래스에서 print 메소드를 보면, 우리는 각 값들을 출력할 때 인덱스 0은 사용자가 보기에 적합하지 않기 때문에
임의로 i+1을 해줬기 때문이다.
따라서 받은 index를 -1을 해서 적용시켜야 알맞은 인덱스를 찾을 수 있다.
그런 후 index가 0보다 작거나 배열의 길이보다 크면 적합한 인덱스가 아니라는 메세지를 주고,
적절히 잘 입력했다면 index를 return 한다.
그리고 다시 위의 if else 문으로 가서 validateIndex 메소드에서 받은 수정하고자 하는 index를 update 메소드에 넣어
수정을 진행한다.
여기까지가 입력에 관한 옵션들이다.
다음은 출력이다.
2번을 눌렀을 때 출력이 진행되는데 역시 null 값인지 아닌지 확인해야한다.
만약 배열이 null이 아니면 있는 값을 그대로 print 메소드를 이용해 보여주면 끝이다.
하지만 null 이라면 입력된 정보가 없다는 경고창을 띄워야한다.
} else if (choice == 2) { // 출력하기 // 출력메소드 실행하되 world가 널인지 체크해서 널 아닐때에 실행 if (world != null) { NationUtil.print(world); } else { // 경고 메세지만 출력 System.out.println("아직 입력된 정보가 없습니다. "); }
Conrona.java의 전체코드 이다.
package coronaProject; import java.util.Scanner; import util.MyScanner; public class CoronaEx { public static void main(String[] args) { Scanner scan = new Scanner(System.in); Nation[] world = null; City[] cities = null; while (true) { // 메뉴를 출력한다. // 1. 세계 현황보기 // 2. 한국 현황보기 // 3. 종료 System.out.println("==== 코로나 상황판 ===="); System.out.println("1. 세계 현황 2. 한국현황 3. 종료"); System.out.print(">>"); int choice = MyScanner.nextInt(scan); // 세계 현황 if (choice == 1) { // 1, 2, 3 옵션 보여주는 메소드 // choice가 1이면 새로 입력, 2면 출력, 3이면 종료 choice = showMenu(scan); if (choice == 1) { // 입력하기 // 입력하기 눌렀을 때 Nation[]이 null 이면 곧장 입력하기 누르고 // 만약 null이 아니면 전체수정인지 개별수정인지 묻는다. if (world == null) { // 비어 있으면 입력하는 메소드 world = NationUtil.start(scan); } else { System.out.println("1. 전체 다시 수정 2. 개별수정"); System.out.print(">>>>"); choice = MyScanner.nextInt(scan); // update 메소드 if (choice == 1) { // 전체 다시 수정 world = NationUtil.start(scan); } else { // 개별 수정 // 현재 상태 전체를 출력하고 // 수정할 나라의 번호 선택 NationUtil.print(world); System.out.print("수정할 번호를 입력하세요 : "); // 번호 수정하는 인덱스 만듦 int index = validateIndex(scan, world.length); // index에 적합한 숫자를 입력받으면 update 메소드 실행 world = NationUtil.update(world, index, scan); } } } else if (choice == 2) { // 출력하기 // 출력메소드 실행하되 world가 널인지 체크해서 널 아닐때에 실행 if (world != null) { NationUtil.print(world); } else { // 경고 메세지만 출력 System.out.println("아직 입력된 정보가 없습니다. "); } } else if (choice == 3) { // 뒤로가기 break; } // 한국현황 } else if (choice == 2) { // 1, 2, 3 옵션 보여주는 메소드 choice = showMenu(scan); if (choice == 1) { // 입력하기 if (cities == null) { cities = CityUtil.start(scan); } else { System.out.println("1. 전체 다시 수정 2. 개별수정"); System.out.print(">>>>"); choice = MyScanner.nextInt(scan); if (choice == 1) { // 전체 수정 cities = CityUtil.start(scan); } else { // 개별 수정 CityUtil.print(cities); System.out.print("수정할 번호를 입력하세요 : "); // 번호 수정하는 인덱스 만듦 int index = validateIndex(scan, cities.length); cities = CityUtil.update(index, scan, cities); } } } else if (choice == 2) { // 출력하기 if (cities != null) { CityUtil.print(cities); } } else { // 뒤로 System.out.println("아직 입력된 정보가 없습니다. "); } // 프로그램종료 } else if (choice == 3) { System.out.println("종료"); break; } } scan.close(); } // 적합한 번호가 나올 때 까지 번호 수정하는 메소드 validateIndex public static int validateIndex(Scanner scan, int length) { System.out.print("수정할 번호를 입력하세요 : "); int index = MyScanner.nextInt(scan) - 1; // i+1로 출력을 임의로 만들었기 때문에 (index값이 0부터 시작해서 출력되면 보기에 안좋으니까..) // 그래서 우리가 입력을 받을 때 사용자 입력 숫자 -1 을 해서 프로그램에 넣는다. while (index < 0 || index >= length) { System.out.println("잘못 입력하셨습니다."); System.out.println("수정할 번호를 입력하세요. "); index = MyScanner.nextInt(scan) - 1; // 여기도 마찬가지로 -1 해주어야한다. // 아니면 1을 수정하라고 했는데 // 보이는건 1번 인덱스(사용자 상의)인데 실제 인덱스인 0(프로그램상의)도 역시 수정이 된다. } return index; } // 1, 2, 3 옵션 보여주는 메소드 public static int showMenu(Scanner scan) { int choice = 0; System.out.println("1. 입력하기 2. 출력하기 3. 뒤로"); System.out.print(">>>"); choice = MyScanner.nextInt(scan); return choice; } }
'프로그래밍 > TIL(국비과정)' 카테고리의 다른 글
TIL #8 - 게시판 프로그램 (0) 2020.04.06 TIL #7 - 로또 프로그램 (0) 2020.04.02 TIL #6 - 배열 활용 (2) (0) 2020.04.01 TIL #6 - 배열 활용 (1) (0) 2020.04.01 TIL #5 - 배열 (0) 2020.03.31