카테고리 없음

Exercise_저장되는 단어장 만들기(메소드, 클래스, 파일저장)

장꾸꾸 2020. 9. 1. 11:55

Point

- Control에 Voca를 집어넣고 Main에서 불러오도록 한다.

 

- package를 Main, Control, Model로 각각 만든다.

모델에는 Voca 클래스를 집어넣고 private으로 설정/ Getter와 Setter를 Generate해준다.

 

- 중복되는 기능은 메소드로 처리해 코드 길이를 줄인다. ex_ 단어 삭제, 수정 등

각각의 메소드로 만들면 후에 오류 위치를 찾는 것도 쉽다

이때, ArrayList, String input, Scanner 같은 것들은 전체 클래스 선언으로 해준다.

 

- io 작업(input/output)은 네트워크 작업과 함께 가장 시간이 많이 드는 작업.

따라서 파일 io도 맨처음 시작에 위치 시켜주어야(전체클래스 선언) 호출할 때, 즉 최초 시작에만 불러오게 된다.

단어 저장은 덮어쓰기로 한다.

파일로딩을 while 문 전에 위치시킨다는 말이다.

 

실행창인 Main

package main;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

import control.Control;

public class Main {

	public static void main(String[] args) {
		new Control().init();
	}

}

 

Voca 클래스

package model;

public class Voca {
	private String eng;
	private String kor;
	
	public Voca(String eng, String kor) {		
		this.eng = eng;
		this.kor = kor;
	}
	public String getEng() {
		return eng;
	}
	public void setEng(String eng) {
		this.eng = eng;
	}
	public String getKor() {
		return kor;
	}
	public void setKor(String kor) {
		this.kor = kor;
	}
}

getter(값을 가져오는)와 setter(값을 넣어주는) 위치시킴

model 패키지는 말그대로 형식을 지정하는 역할

 

Control 클래스

package control;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

import model.Voca;

public class Control {
	String input = "";
	Scanner scan = new Scanner(System.in);
	ArrayList<Voca> vocaArr = new ArrayList<>();

	private void saveData() {
		FileWriter fw;
		try {
			fw = new FileWriter("c:/my/voca.txt"); // 덮어쓰기 , true 붙여쓰기
			for (int i = 0; i < vocaArr.size(); i++) {
				String eng = vocaArr.get(i).getEng();
				String kor = vocaArr.get(i).getKor();
				String data = eng + "," + kor+"\r\n";
				fw.write(data);
			}
			fw.close();
			System.out.println("저장 완료");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void readData() {
		try {
			BufferedReader br = new BufferedReader(new FileReader("c:/my/voca.txt"));
			while (true) {
				String line = br.readLine();
				if (line == null) // 읽어올 데이터가 없다
					break;			
				String[] temp = line.split(",");
				vocaArr.add(new Voca(temp[0], temp[1]));
			}
			br.close();
			System.out.println("총 "+vocaArr.size() +"개 단어 로드");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void showVoca() {
		System.out.println("[ 현 단어장 " + vocaArr.size() + "개 ]");
		for (int i = 0; i < vocaArr.size(); i++) {
			System.out.println((i + 1) + ". " + vocaArr.get(i).getEng() + " : " + vocaArr.get(i).getKor());
		}
	}

	private void addVoca() {
		System.out.println();
		System.out.println("추가할 단어 입력하셈");
		input = scan.nextLine();
		System.out.println("한글 뜻?");
		String kor = scan.nextLine();
		vocaArr.add(new Voca(input, kor));
	}

	private void deleteVoca() {
		System.out.println();
		System.out.println("삭제할 단어를 선택해 주세요");
		input = scan.nextLine();
		int temp = Integer.parseInt(input);
		vocaArr.remove(temp - 1);
	}

	private void updateVoca() {
		System.out.println();
		System.out.println("수정할 단어를 선택해 주세요");
		input = scan.nextLine();
		int temp = Integer.parseInt(input);
		System.out.println("수정할 단어 입력하셈");
		input = scan.nextLine();
		vocaArr.get(temp - 1).setEng(input);
//		engArr.set(temp - 1, input);
		System.out.println("수정할 한글뜻 입력하셈");
		input = scan.nextLine();
		vocaArr.get(temp - 1).setKor(input);
//		korArr.set(temp - 1, input);
	}

	private void scrambleGame() {
		Random rd = new Random();
		int ranNum = rd.nextInt(vocaArr.size());
		String answer = vocaArr.get(ranNum).getEng();

		String question = "";

		ArrayList<String> tempArr = new ArrayList<String>();
		for (int i = 0; i < answer.length(); i++) {
			tempArr.add(answer.substring(i, i + 1));
		}

		while (tempArr.size() > 0) {
			ranNum = rd.nextInt(tempArr.size());
			question = question + tempArr.get(ranNum);
			tempArr.remove(ranNum);
		}

		String temp = answer;
//		while(temp.length() > 0) {
//			ranNum = rd.nextInt(temp.length());
//			question = question + temp.substring(ranNum, ranNum+1);
//			temp = temp.substring(0, ranNum) + temp.substring(ranNum+1);					
//			System.out.println("ranNum: "+ ranNum +",  question: "+question +", temp: "+ temp);
//		}
		System.out.println("문제: " + question);
		input = scan.nextLine();
		if (input.equals(answer)) {
			// 정답
		} else {
			// 오답
		}
	}

	public void init() {
		//파일로딩
		File file = new File("c:/my/voca.txt");
		if(file.exists()) {
			readData();
		}
		
		while (true) {
			System.out.println("길이: " + vocaArr.size());
			System.out.println("----------------------");
			System.out.println("|  뭐할래?");
			System.out.println("|  1. 추가    2. 삭제    3. 수정   4. 게임   5. 끝내기");
			System.out.println("----------------------");

			String input = scan.nextLine();

			if (input.equals("1")) {
				showVoca();
				addVoca();
				saveData();
			} else if (input.equals("2")) {
				showVoca();
				deleteVoca();
				saveData();
			} else if (input.equals("3")) {
				showVoca();
				updateVoca();
				saveData();
			} else if (input.equals("4")) {
				scrambleGame();

			} else if (input.equals("5")) {
				break;
			} else {
				System.out.println("또이 또이 안 치냐??");
			}
			showVoca();

			System.out.println();
			System.out.println();
		}
	}
}

 Control 클래스 내에서 각 기능을 메소드로 분리한다. ***

단어장 저장하기 -> private void saveData()

단어장 읽어오기 -> private void readData()

단어장 보여주기 -> private void showVoca()

단어 추가하기 -> private void addVoca()

단어 삭제하기 -> private void deleteVoca()

단어 수정하기 -> private void updateVoca()

단어 게임하기 -> private void scrambleGame() 

 

EX_ 파일 기능

	private void saveData() {
		FileWriter fw;
		try {
			fw = new FileWriter("c:/my/voca.txt"); // 덮어쓰기 , true 붙여쓰기
			for (int i = 0; i < vocaArr.size(); i++) {
				String eng = vocaArr.get(i).getEng();
				String kor = vocaArr.get(i).getKor();
				String data = eng + "," + kor+"\r\n";
				fw.write(data);
			}
			fw.close();
			System.out.println("저장 완료");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

	private void readData() {
		try {
			BufferedReader br = new BufferedReader(new FileReader("c:/my/voca.txt"));
			while (true) {
				String line = br.readLine();
				if (line == null) // 읽어올 데이터가 없다
					break;			
				String[] temp = line.split(",");
				vocaArr.add(new Voca(temp[0], temp[1]));
			}
			br.close();
			System.out.println("총 "+vocaArr.size() +"개 단어 로드");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

 

 

BufferedReader : 콘솔로부터 라인 단위로 읽기

import java.io.BufferedReader;

FileWriter :  텍스트 데이터를 파일에 저장할 때 사용하는 문자 기반 스트림

		FileWriter fw = new FileWriter("C:/Temp/file.txt,true")
        FileWriter fw = new FileWriter(file, true);

기존의 파일 내용 끝에 데이터를 추가할 경우는 두번째 매개값으로 true를 준다. 디폴트값이 false이므로 덮어쓰고 싶으면 true를 안쓰면 된다.

 

try / catch : 예외 처리

try{
    //에러가 발생할 수 있는 코드
    throw new Exception(); //강제 에러 출력 
}catch (Exception e){
    //에러시 수행
     e.printStackTrace(); //오류 출력(방법은 여러가지)
     throw e; //최상위 클래스가 아니라면 무조건 던져주자
}finally{
    //무조건 수행
} 

finally는 생략가능하다.

 

참고_

e.getMessage() = 에러 이벤트와 함께 들어오는 메세지를 출력한다.

e.getMessage(): 출력문구

 

e.toString() = 에러 이벤트의 toString()을 호출해서 간단한 에러 메시지를 확인한다.

e.toString(): java.lang.Exception: 출력문구

 

e.printStackTrace() = 에러 메세지의 발생 근원지를 찾아서 단계별로 에러를 출력한다.

e.printStackTrace(): java.lang.Exception: 출력문구

at ExThrowException.main(ExeThrowException.java:6)