Что я сделал, так это сделал проверку ошибок, которая повторяется каждый раз, когда пользователь вводит недопустимое имя файла:

    public static Scanner readFile(String filename){
    Scanner stdin = new Scanner(System.in);
    File input = new File(filename);
    Scanner sc = null;
    do {
        try {
            sc = new Scanner(input);
    }
        catch(FileNotFoundException e) {
            System.out.println("Filename not valid. Please try again:");
            filename = stdin.nextLine();
    }
} while (!new File(filename).exists()); 
            return sc;
    }

У меня также достаточно метода, который читает этот файл и помещает данные в массив:

public static CO2Data[] readData(String filename){
File input = new File(filename);
    Scanner sc = null;
    try{
        sc = new Scanner(input);
    }
    catch(FileNotFoundException e){
        System.out.println("Filename not valid");
        System.exit(-1);
    }
String info = sc.nextLine();
int total = sc.nextInt();
CO2Data[] arr = new CO2Data[total];
for(int i=0; i<10;i++){
    arr[i] = new CO2Data();
    }
for(int i=0; i<10;i++){ 
    arr[i].setCountry(sc.next());
    arr[i].setTotalCO2(sc.nextDouble());
    arr[i].setRoadCO2(sc.nextDouble());
    arr[i].setCO2PerPerson(sc.nextDouble());
    arr[i].setCarsPerPerson(sc.nextInt());
    }
return arr;
}

Проблема в том, что если я сначала ввожу недопустимое имя файла, а затем допустимое имя, программа говорит, что файл недействителен, однако, если я сначала ввожу действительное имя файла, программа работает нормально. Итак, почему ввод действительного имени файла сначала работает нормально, но ввод неверного имени, а затем действительного имени заставляет программу выдавать мне сообщение об ошибке.

0
David Rolfe 5 Дек 2014 в 23:03

2 ответа

Итак, давайте пройдемся по полному сценарию:

Если вы введете неверное имя файла, код переместится в блок catch, ожидая, пока вы введете новое имя файла со строкой

filename = stdin.nextLine();

Вы вводите действительное имя файла, и переменное имя файла сбрасывается на новое имя файла (пока хорошо)

Затем мы переходим к блоку While, который будет проверять, существует ли файл (что он и делает!), поэтому мы переходим к оператору return (который содержит проблему)

В операторе return вы возвращаете сканер, который содержал предыдущее недопустимое имя файла. Вам нужно переделать сканер с новым файлом, прежде чем вернуть его.

Я бы, вероятно, отредактировал цикл while для чтения

public static Scanner readFile(String filename){
Scanner stdin = new Scanner(System.in);
File input = new File(filename);
Scanner sc = null;
do {
    try {
        input = new File(filename);
        sc = new Scanner(input);
    }catch(FileNotFoundException e) {
        System.out.println("Filename not valid. Please try again:");
        filename = stdin.nextLine();
    }
} while (!input.exists());
    return sc;
}

Таким образом, мы создаем новый класс File после получения действительного ввода, а затем возвращаем новый Scanner, содержащий новый input

0
chancea 5 Дек 2014 в 23:28
Возникла проблема с оператором возврата. Чтобы вернуть новый сканер, необходимо либо поймать, либо сгенерировать исключение filenotfound.
 – 
David Rolfe
5 Дек 2014 в 23:26
Эээ, это было хорошо, лол, извините, пятница, мой мозг стал медленнее
 – 
chancea
5 Дек 2014 в 23:29
Даже отредактированная программа все еще дает мне ту же проблему. Мне интересно, проблема в этом методе или в том, как эти методы называются?
 – 
David Rolfe
6 Дек 2014 в 00:10
Хм. не могли бы вы обновить свой ответ сообщением об ошибке? Возможно, трассировка стека, если она у вас есть
 – 
chancea
6 Дек 2014 в 01:06

Вы не создаете новый ввод из имени файла, поэтому вы всегда используете первое имя файла в Scanner. Это должно работать:

ОБНОВЛЕННЫЙ КОД

public static Scanner readFile(String filename){
    Scanner stdin = new Scanner(System.in);
    Scanner sc = null;
    File input;
    do {
        input = new File(filename);
        try {
            sc = new Scanner(input);
        }
        catch(FileNotFoundException e) {
            System.out.println("Filename not valid. Please try again:");
            filename = stdin.nextLine();
        }
    } while (!input.exists());
    return sc;
}
0
jakub.petr 5 Дек 2014 в 23:42
С этим кодом происходит то же самое, что и раньше, когда он работает, если я ввожу действительное имя файла в первый раз, но не работает, если я помещаю недопустимое имя файла, за которым следует действительное имя файла.
 – 
David Rolfe
5 Дек 2014 в 23:26
Вам все равно нужно изменить строку while, чтобы проверить, существует ли input, а не новый файл, иначе возникнет та же проблема. ^^
 – 
chancea
5 Дек 2014 в 23:26
Проблема 2. Я изменил цикл while на выражение while (!input.exists()); однако я получаю сообщение об ошибке компилятора, в котором говорится, что ввод переменной не найден. Я был уверен, что объявил это ранее в своем коде, но компилятор не может его найти.
 – 
David Rolfe
5 Дек 2014 в 23:30
О, это потому, что он переместил строку File input = new... внутрь цикла. Если вы оставите эту строку снаружи и просто используете input = new File(filename);, это сработает. (это то, что я сделал в своем обновленном ответе)
 – 
chancea
5 Дек 2014 в 23:32
Вам не нужно повторно использовать входную переменную, эта версия должна работать. Я попробовал, и он запрашивает имя файла, пока не получит существующий файл, а затем вернет для него сканер. Где вы используете эту функцию?
 – 
jakub.petr
5 Дек 2014 в 23:38