简体   繁体   中英

How to read each element from a txt file using scanner class?

I am trying to get a scanner function to read each element from a text file, and place it in a 2d array. I am using the scanner function on java, and using for and while loops to place the items in the array as char variables.

the example txt file i am using is .brd format and is:

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

I have tried using scanner.next(), scanner.nextByte() and scanner.next().chatAt(i) which is the closest i got to solving it. But when i use it. With i being the index for the current row. But instead of going across and scanning each element in goes down diagonally.

My current code is i and j are the amount of rows and columns in the file excluding the first line.

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++;    
         }

I want it to go across every element(only consisting of one character for example just ".") in the row and add it in the 2d array with the right if statment. It is adding into the array correctly, but is only doing the elements diagonally.

In order to properly declare and initialize an array you need to know how many elements are going to reside within that array. For a 2D Array you will need to know how many rows (String[rows][]) within the Array will need to be initialized. There can be any number of columns for each row in a 2D Array, for example:

/* 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"}
                     };

To get the number of rows you will need to set your array you would need to make a pass over the file to count the number of valid data lines (rows) so as to initialize the 2D Array, like this,

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();
}

Now you can re-read the file and fill the Array as you need, for example, here is the entire code to initialize and fill the 2D String Array named 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();
}

If you want to display the contents of your 2D Array into the Console Window then you might do something like this:

// 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());
}

Placing File Data Into An ArrayList To Create A 2D Array:

Reading the data file into an ArrayList however can make things somewhat easier since an ArrayList or List Interface can dynamically grow as needed and you only need to read the file once. Size of the required Array can be determined by the size of the ArrayList. Here is an example doing the same thing as above except utilizing an 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM