[자바프로그래밍] FileWriter를 while문에서 돌릴 때, 에러가 납니다.


안녕하세요. 자바를 배우고 있는 학생입니다. 학교 과제로 다이어리 프로그램을 만들고있는데요. 자바에서 FileWriter, FileReader 등 File클래스를 이용하여 일기나 스케줄을 메모장으로 저장하고, 저장된 메모장 내용을 읽기를 구현했는데, 스케줄이나 일기를 저장할 때 내용을 입력하고 엔터와 Ctrl + Z를 누르는 순간 NoSuchElementException에러가 납니다(첨부한사진).

어떻게 해결할 수 있을까요?? (자바 이클립스를 사용합니다.)

아래는 코드입니다.

/*DiaryMenu.java 메인메소드가 있는 클래스*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;
public class DiaryMenu{
    public static void main (String args[]) throws IOException{
        Scanner scanner = new Scanner(System.in);
        int choice =0;
        int choice2 =0;
        ScheduleAdd scheduleAdd = new ScheduleAdd();
        WriteDiary writeDiary = new WriteDiary();

        while (choice!=5) {
            System.out.print("(1) 스케줄 (2) 일기 (3) 학점 계산기 (4) 사용자 설정 (5) 종료 >>");
            choice = scanner.nextInt();

            switch (choice) {
            case 1:
                System.out.print("(1) 달력보기 (2) 스케줄 등록 (3) 스케줄 보기  >>");
                choice2 = scanner.nextInt();
                if (choice2 == 1) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
                       System.out.print("년도를 입력하시오: " ); 
                       int year = Integer.parseInt(br.readLine()); 
                       System.out.print("월 입력하시오: " ); 
                       int month = Integer.parseInt(br.readLine()); 
                       Calender cal = new Calender(year, month); 
                       cal.Display();
                }

                if (choice2 == 2) {//스케줄 등록
                    scheduleAdd.scheduleAdd();
                }

                if (choice2 == 3) {//스케줄 보기
                }
                else {
                    System.out.print("잘못입력하셨습니다.");
                }

                break;
            case 2:
                System.out.print("(1)일기 쓰기 (2)일기 읽기 >>");
                choice2 = scanner.nextInt();

                if (choice2 == 1) {
                    writeDiary.addDiary();
                }

            }
        }
    }
}

/*ScheduleAdd.java (1) 스케줄 -> (2) 스케줄등록*/
import java.io.*;
import java.util.Scanner;

public class ScheduleAdd {
    InputStreamReader in = new InputStreamReader(System.in);
    FileWriter sch = null;
    String schedule_day = null;

    Scanner scanner = new Scanner(System.in);

    public void scheduleAdd () {
        System.out.print("스케줄 등록할 날짜 입력 (ex:160611) >>");
        schedule_day = scanner.nextLine();
        int c;
        //System.out.println();
        System.out.print("스케줄 내용 입력 후 엔터, ctrl+z>>");

        try {
            sch = new FileWriter("d:\\KNKDiary\\schedule\\"+schedule_day+".txt");

            while ((c=in.read())!= -1) {
                sch.write(c);
            }
            in.close();
            sch.close();
        }
        catch (IOException e) {
            System.out.println("입출력 오류");
        }
        System.out.println("저장되었습니다.");
    }
}

이미지

  • 2016년 06월 12일에 작성됨

조회수 287


1 답변


좋아요
2
싫어요
채택취소하기

윈도우완경에서 콘솔에서 Ctrl+Z 를 입력하는 것은 EOF(End of File)을 애플리케이션에 보내는 것과 같습니다. (유닉스에서는 Ctrl+D)

일반적으로 EOF는 파일의 끝임으로 InputStream에게는 더 이상 읽을 것이 없다는 의미가 됩니다.

System.in 에서 EOF로 마킹되면 그 이후에는 모두 EOF만 읽게 되며, 더이상의 입력이 안되는 것으로 알고 있습니다.

우선 에러 없이 종료하려면 다음과 같이 코드를 수정하면 될 것 같습니다.

while (choice!=5) {
            System.out.print("(1) 스케줄 (2) 일기 (3) 학점 계산기 (4) 사용자 설정 (5) 종료 >>");
            if( scanner.hasNext() ) {
                choice = scanner.nextInt();
            } else {
                // 종료.
                break;
            }

수정답변:

수정 예시: scheduleAdd 메서드

다음과 같이 변경해보세요.

private static String TERMINATE = "."; // 종료문자
public void scheduleAdd() {
     System.out.print("스케줄 등록할 날짜 입력 (ex:160611) >>");
     schedule_day = scanner.nextLine();
     //System.out.println();
     System.out.print("스케줄 내용 입력 후 엔터, 종료하려면, 마지막줄에 마침표(.)만 입력하세요>>");}

     int lines = 0; // 팁: 한줄도 입력되지 않은 경우 삭제하기.
     Path path = Paths.get("d:\\KNKDiary\\schedule\\"+schedule_day+".txt");
     // 자바 NIO2 사용시 예,  java.nio.file.Path와 java.nio.file.Paths를 import 해야함.
     try(sch = new FileWriter(path.toFile())) {
        // Java7 이후부터 Autoclose를 지원합니다.
        // try 구문이 끝나면 자동으로 close합니다.

        while(scanner.hasNext()) {
            String line = scanner.nextLine();
            if( TERMINATE.equals(line) ) { // 현재 글자가 마침표이면.
                sch.flush();
                break;
            }
            lines++;
            sch.write(line);  // scanner로 line을 읽으면, 끝의 줄바꿈 문자가 제거됨.
            sch.write(System. lineSeparator()); // 줄바꿈. Java7 부터는 줄구분자는 System.lineSeparator() 을 사용하면 됩니다.            
        }
     } catch(IOException e) {
        System.out.println("입출력 오류");
     }
    if(lines == 0) { // 팁: 한줄도 입력하지 않은 경우, 취소 처리함.
        Files.delete(path); // 파일 삭제. java.nio.file.Files를 import 해야함.
        System.out.println("취소되었습니다.");
    } else {
        System.out.println("저장되었습니다.");
    }

}

  • 2016년 06월 13일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

  • 지금 실행시켜보니 오류는 안뜨는데 ctrl z를 이용한 메뉴를 사용하면 프로그램 자체가 종료되어버리네요ㅠㅠ 정상적으로 계속 while문이 돌수있게 하는 방법은 없을까요??    heerim12   2016.6.13 12:36     
  • 음... 아마 순수하게 Java로 만으로는 안될 것 같습니다. Ctrl+Z(EOF)를 입력하면 System.in으로부터 아무 내용도 읽을 수 없습니다. 아마 스케줄 내용 입력 종료방식으로 마지막 라인에 "." 마침표 하나만 입력하는 식으로 바꾸지 않으면 힘들것 같에요.    허대영(Daeyoung Heo)   2016.6.13 16:53     
  • 답변 정말 감사합니다.ㅠㅠ 그렇다면 혹시 마지막라인에 마침표를 하나만 입력해서 저장하는 방법에 대해 설명해주실수있나요?? 많이 어려운가요??ㅠㅠ    heerim12   2016.6.13 18:18     
  • 수정한 내용을 답변에 기록하였습니다. 참고하세요.    허대영(Daeyoung Heo)   2016.6.13 18:43     
  • 정말 감사드립니다. 답변한대로 바꿨더니 와일문이 안끊기네요ㅠㅠ 도움이 많이 되었습니다 감사합니다...    heerim12   2016.6.13 23:00     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close