Как прочитать каждый элемент из текстового файла с помощью класса сканера? - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь заставить функцию сканера считывать каждый элемент из текстового файла и помещать его в двумерный массив. Я использую функцию сканера в java и использую циклы for и while для размещения элементов в массиве как переменных типа char.

Пример текстового файла, который я использую, имеет формат .brd:

format 1
......
.C..D.
..BA..
......

Я пытался использовать scanner.next (), scanner.nextByte () и scanner.next (). ChatAt (i), который ближе всего подходит к его решению. Но когда я использую это. Я являюсь индексом для текущей строки. Но вместо того, чтобы просматривать и сканировать каждый элемент, он идет вниз по диагонали.

Мой текущий код i и j - количество строк и столбцов в файле, исключая первую строку.

try {
            reader = new Scanner(new File(file));
        } catch (FileNotFoundException ex){
            Logger.getLogger(InputReader.class.getName()).log(Level.SEVERE, null, ex);
        }

        s = reader.nextLine();
        char gridE;
        String[][] grid = new String[rows][length];
        int j =0;
        while (reader.hasNextLine()) {

            for(int i = 0; i < length;i++){


                gridE = reader.next().charAt(i);

                String b = "5";

                if(gridE == '.'){
                    grid[i][j] = "blank";
                } else if(gridE == 'A' || gridE == 'B' || gridE == 'C' || gridE == 'D'){
                    grid[i][j] = "Robot";
                } else if(gridE == '+'){
                    grid[i][j] = "Gear";
                } else if(gridE == '-') {
                    grid[i][j] = "Gear";
                } else if(gridE == '1') {
                    grid[i][j] = "Flag1";
                } else if(gridE == '2') {
                    grid[i][j] = "Flag2";
                } else if(gridE == '3') {
                    grid[i][j] = "Flag3";
                } else if(gridE == '4') {
                    grid[i][j] = "Flag4";
                } else if(gridE == 'x') {
                    grid[i][j] = "Pit";
                } else if(gridE == 'v') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == '>') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == '<') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == '^') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 'N') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 'n') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 'S') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 's') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 'W') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 'w') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 'E') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == 'e') {
                    grid[i][j] = "ConveyorBelt";
                } else if(gridE == '[') {
                    grid[i][j] = "LaserEmitter";
                } else if(gridE == ']') {
                    grid[i][j] = "LaserReciever";
                } else if(gridE == '(') {
                    grid[i][j] = "LaserReciever";
                } else if(gridE == ')') {
                    grid[i][j] = "LaserRecieve";
                } 




            }
                j++;    
         }

Я хочу, чтобы он прошел по каждому элементу (состоящему только из одного символа, например, просто ".") В строке и добавил его в массив 2d с правильным положением if. Он правильно добавляет в массив, но делает элементы только по диагонали.

1 Ответ

1 голос
/ 28 марта 2019

Чтобы правильно объявить и инициализировать массив, вам нужно знать, сколько элементов будет находиться в этом массиве. Для двумерного массива вам нужно знать, сколько строк (String [row] []) в массиве нужно будет инициализировать. Для каждой строки в 2D-массиве может быть любое количество столбцов, например:

/* A 4 Row 2D String Array with multiple 
   number of columns in each row.  */
String[][] myArray = {
                     {"1", "2", "3"},
                     {"1", "2", "3", "4", "5"},
                     {"1"},
                     {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}
                     };

Чтобы получить количество строк, вам нужно установить массив, вам нужно будет выполнить обход файла, чтобы подсчитать количество допустимых строк данных (строк), чтобы инициализировать 2D-массив вот так

String file = "File.txt";
String[][] myArray = null;
try {
    // Get number of actual data rows in file... 
    Scanner reader = new Scanner(new File(file));
    reader.nextLine();  // Read Past Header Line
    int i = 0;
    while (reader.hasNextLine()) {
        String fileLine = reader.nextLine().trim();
        // Ignore Blank Lines (if any)
        if (fileLine.equals("")) {
            continue;
        }
        i++;
    }
    // Initialize the Array
    myArray = new String[i][];
}
catch (FileNotFoundException ex) {
    ex.printStackTrace();
}

Теперь вы можете перечитать файл и заполнить массив так, как вам нужно, например, вот весь код для инициализации и заполнения двумерного массива строк с именем myArray :

String file = "File.txt";
String[][] myArray = null;
try {
    // Get number of actual data rows in file... 
    Scanner reader = new Scanner(new File(file));
    reader.nextLine();  // Read Past Header Line
    int i = 0;
    while (reader.hasNextLine()) {
        String fileLine = reader.nextLine().trim();
        // Ignore Blank Lines (if any)
        if (fileLine.equals("")) {
            continue;
        }
        i++;
    }
    // Initialize the Array
    myArray = new String[i][];

    // Re-Read file and fill the 2D Array...
    i = 0;
    reader = new Scanner(new File(file));
    reader.nextLine();  // Read Past Header Line

    while (reader.hasNextLine()) {
        String fileLine = reader.nextLine().trim();
        // Ignore Blank Lines (if sny)
        if (fileLine.equals("")) {
            continue;
        }
        // Slpit the read in line to a String Array of characters
        String[] lineChars = fileLine.split("");
        /* Iterate through the characters array and translate them...
           Because so many characters can translate to the same thing
           we use RegEx with the String#matches() method. */
        for (int j = 0; j < lineChars.length; j++) {
            // Blank
            if (lineChars[j].matches("[\\.]")) {
                lineChars[j] = "blank";
            }
            // Robot
            else if (lineChars[j].matches("[ABCD]")) {
                lineChars[j] = "Robot";
            }
            // Gear
            else if (lineChars[j].matches("[\\+\\-]")) {
                lineChars[j] = "Gear";
            }
            // FlagN
            else if (lineChars[j].matches("[1-4]")) {
                lineChars[j] = "Flag" + lineChars[j];
            }
            // Pit
            else if (lineChars[j].matches("[x]")) {
                lineChars[j] = "Pit";
            }
            // ConveyotBelt
            else if (lineChars[j].matches("[v\\<\\>\\^NnSsWwEe]")) {
                lineChars[j] = "ConveyorBelt";
            }
            // LaserEmitter
            else if (lineChars[j].matches("[\\[]")) {
                lineChars[j] = "LaserEmitter";
            }
            // LaserReciever
            else if (lineChars[j].matches("[\\]\\(\\)]")) {
                lineChars[j] = "LaserReciever";
            }

            // ............................................
            // ... whatever other translations you want ...
            // ............................................

            // A non-translatable character detected.
            else {
                lineChars[j] = "UNKNOWN";
            }
        }
        myArray[i] = lineChars;
        i++;
    }
    reader.close(); // We're Done - close the Scanner Reader
}
catch (FileNotFoundException ex) {
    ex.printStackTrace();
}

Если вы хотите отобразить содержимое вашего 2D-массива в окне консоли, вы можете сделать что-то вроде этого:

// Display the 2D Array in Console...
StringBuilder sb;
for (int i = 0; i < myArray.length; i++) {
    sb = new StringBuilder();
    sb.append("Line ").append(String.valueOf((i+1))).append(" Contains ").
                append(myArray[i].length).append(" Columns Of Data.").
                append(System.lineSeparator());
    sb.append(String.join("", Collections.nCopies((sb.toString().length()-2), "="))).
                append(System.lineSeparator());

    for (int j = 0; j < myArray[i].length; j++) {
        sb.append("Column ").append(String.valueOf((j+1))).append(": -->\t").
                append(myArray[i][j]).append(System.lineSeparator());
    }
    System.out.println(sb.toString());
}

Размещение данных файла в ArrayList для создания двумерного массива:

Считывание файла данных в ArrayList, однако, может несколько упростить ситуацию, поскольку ArrayList или List Interface могут динамически расти по мере необходимости, и вам нужно только прочитать файл один раз. Размер требуемого массива может быть определен размером ArrayList. Вот пример, делающий то же самое, что и выше, за исключением использования ArrayList:

String file = "File.txt";
String[][] myArray = null;
ArrayList<String> dataList = new ArrayList<>();
try {
    // Get number of actual data rows in file... 
    Scanner reader = new Scanner(new File(file));
    reader.nextLine();  // Read Past Header Line
    while (reader.hasNextLine()) {
        String fileLine = reader.nextLine().trim();
        // Ignore Blank Lines (if any)
        if (fileLine.equals("")) {
            continue;
        }
        dataList.add(fileLine); // Add data line to List
    }
    reader.close(); // Close the Scanner Reader - Don't need anymore
}
catch (FileNotFoundException ex) {
    Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
}

// Initialize the Array
myArray = new String[dataList.size()][];

// Iterate through the ArrayList and retrieve the data
for (int i = 0; i < dataList.size(); i++) {
    String dataLine = dataList.get(i).trim();

    // Split the data line into a String Array of characters
    String[] lineChars = dataLine.split("");

    /* Iterate through the characters array and translate them...
       Because so many characters can translate to the same thing
       we use RegEx with the String#matches() method. */
    for (int j = 0; j < lineChars.length; j++) {
        // Blank
        if (lineChars[j].matches("[\\.]")) {
            lineChars[j] = "blank";
        }
        // Robot
        else if (lineChars[j].matches("[ABCD]")) {
            lineChars[j] = "Robot";
        }
        // Gear
        else if (lineChars[j].matches("[\\+\\-]")) {
            lineChars[j] = "Gear";
        }
        // FlagN
        else if (lineChars[j].matches("[1-4]")) {
            lineChars[j] = "Flag" + lineChars[j];
        }
        // Pit
        else if (lineChars[j].matches("[x]")) {
            lineChars[j] = "Pit";
        }
        // ConveyotBelt
        else if (lineChars[j].matches("[v\\<\\>\\^NnSsWwEe]")) {
            lineChars[j] = "ConveyorBelt";
        }
        // LaserEmitter
        else if (lineChars[j].matches("[\\[]")) {
            lineChars[j] = "LaserEmitter";
        }
        // LaserReciever
        else if (lineChars[j].matches("[\\]\\(\\)]")) {
            lineChars[j] = "LaserReciever";
        }

        // ............................................
        // ... whatever other translations you want ...
        // ............................................

        // A non-translatable character detected.
        else {
            lineChars[j] = "UNKNOWN";
        }
    }
    myArray[i] = lineChars;
}
...