Search code examples
javalinuxwindowsjava.util.scannernosuchelementexception

Why my Java program works perfectly in windows but it's a disaster in linux?


I wrote a program that reads a text file, deletes the requested string and rewrites it without the string. This program takes three arguments from the terminal: 1) the input file 2) the string 3) the output file.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

class wordfilter {
    public static void main(String[] args) {
        Scanner scanner = new Scanner("");
        Scanner conteggio = new Scanner("");
        int numel = 0;
        File file = new File(args[0]); // Argomento 0: il file
        try {
            conteggio = new Scanner(file);
        }
        catch (FileNotFoundException e) {
            System.out.println("File non trovato");
        }

        while (conteggio.hasNext()) {
            numel++;
            conteggio.next();
        }
        conteggio.close();
        String[] lettura = new String[numel];
        int i = 0;
        try {
            scanner = new Scanner(file);
        }
        catch (FileNotFoundException e) {
            System.out.println("File non trovato");
        }
        while (scanner.hasNextLine()) {
            lettura[i] = scanner.next();
            i++;
        }
        System.out.println("Contarighe -> " + numel);
        for (i = 0; i < lettura.length; i++) {
            System.out.println("Elemento " + i + " - > " + lettura[i]);
        }
        scanner.close();
        String escludi = args[1]; // Argomento 1: il filtro
        String[] filtrato = rimuovi(escludi, lettura);
        if (args.length == 3) stampaSuFile(filtrato, args[2]);
    }
    public static String[] rimuovi(String esclusione, String[] input) {
        String[] nuovoV;
        String escludi = esclusione;
        int dim = 0;
        for (int i = 0; i < input.length; i++) {
            if (!input[i].equals(escludi))
                dim++;
        }
        nuovoV = new String[dim];

        int j = 0;
        for (int i = 0; i < input.length; i++) {
            if (!input[i].equals(escludi)) {
                nuovoV[j] = input[i];
                j++;
            }
            ;
        }
        return nuovoV;
    }

    public static void stampaSuFile(String[] out, String path) {
        String closingstring = "";
        File destinazione = new File(path);
        try {
            destinazione.createNewFile();
        } catch (IOException e) {
            System.out.println("Errore creazione file");
        }
        try {   
            FileWriter writer = new FileWriter(destinazione);
            for (int i = 0; i < out.length; i++)
                writer.write(out[i] + (i == (out.length-1) ? closingstring : " "));
            writer.close();
            System.out.println("Scrittura eseguita correttamente");
        } catch (IOException e) {
            System.out.println("Errore scrittura file");
        }
    }
}

On Windows no problem, it works perfectly.

On Linux instead when i write something like java wordfilter in.txt word out.txt

I get

Exception in thread "main" java.util.NoSuchElementException
    at java.base/java.util.Scanner.throwFor(Scanner.java:937)
    at java.base/java.util.Scanner.next(Scanner.java:1478)
    at wordfilter.main(wordfilter.java:42)

What's the problem? It's because of some difference on linux?


Solution

  • You're mixing line and token based functions, :hasNextLine() and next(). If the input ends with a line feed (typical on Linux) hasNextLine returns true at the end of the file, but there is no next "item".

        while (scanner.hasNextLine()) {
            lettura[i] = scanner.next();
            i++;
        }
    

    You should use either hasNext with next, or hasNextLine with nextLine, mixing them is confusing.

        while (scanner.hasNext()) {
            lettura[i] = scanner.next();
            i++;
        }