1

Need to read a set of text string files into a 2D array. The text string format looks like this, each line ends with "\n" with various length

    "dog", "runs", "fast"
    "birds", "flies", "high"
    "baby", "cries", "often", "in the evening"
    "He", "works"
    ....

Would like to get the 2D array output below:

  { {"dog", "runs", "fast"}, {"birds", "flies", "high"}, 
    {"baby", "cries", "often", "in the evening"}, {"He", "works"}, 
     ...
  }

Thinking to use StringBuilder to read each line from a file and append it to a 2D Object [][] array (but used String [][] instead). The following codes are my initial attemps - not pretty, but not working either.

                   import java.io.*;
                   import java.util.*;

                  public class My2DArrayTest
                          {
                  public static void main(String args[])
                           {

                String[][] myString = new String[4][3];

                        try
                               {
                        FileReader file = new FileReader("MyTestFile.txt");
                        BufferedReader reader = new BufferedReader (file);
                         String strLine;
                          String EXAMPLE_TEST;  
                           for (int row = 0;  row < 4;  row++) {
                      for (int column = 0;  column < 3;  column++) {
                            while ((strLine = reader.readLine()) != null{

                        if (strLine.length() > 0) {
                      EXAMPLE_TEST = strLine;
                           System.out.println ("This is EXAMPLE_TEST: " +   
                                     EXAMPLE_TEST);


               myString[row][column]=EXAMPLE_TEST;
               System.out.println("Current row: " + row);
               System.out.println("Current column: " + column);
               System.out.println("This is myString Array:" + 
                                    myString[row][column] + " ");
                }
                  }  
                                     }
                                                              }
                               file.close();

                   }   catch( IOException ioException ) {}
                                 }
                                      }
6
  • if you don't know beforehand how many rows it has, you need to scan the file first to get this number. Java arrays are somewhat static and you need to know how many rows and columns your 2D structure will have. Commented Jul 24, 2014 at 4:15
  • I've done something like this before and used an ArrayList (which expands automatically) to hold the rows of the array. Call toArray() on the ArrayList at the end to get the full array. Commented Jul 24, 2014 at 4:17
  • Hi @HappyJubliee - we're not likely to write (or rewrite) your code for you. So how about you have a go at it yourself and see at what stage you get stuck - then come back to us with what you've done, and we'll help you get over that bit. :) Commented Jul 24, 2014 at 4:17
  • Is the input formated exactly like "a", "b", "c"? Or is a b c or a,b,c or abc etc? Commented Jul 24, 2014 at 10:04
  • @xgeorgekx - yes the format is exactly like "a", "b", "c" Commented Jul 24, 2014 at 13:46

5 Answers 5

1

First of all, you will have to decide how to handle the fact that you don't know the number of lines at start. You could:

  1. Count lines in first go to create result array of desired size, then read your file again and fill that array with data.
  2. Store your lines inside a List instead.

(i will choose 2) Second, what characters you want to allow inside your strings? for example " or \n (newline) can make things more complicated since you would have to escape them, but let's assume that these characters will be banned (and also ,, so we can split more easily)

Scanner in = new Scanner(new File("strings.test"));
List<String[]> lines = new ArrayList<>();
while(in.hasNextLine()) {
    String line = in.nextLine().trim();
    String[] splitted = line.split(", ");
    for(int i = 0; i<splitted.length; i++) {
        //get rid of additional " at start and end
        splitted[i] = splitted[i].substring(1, splitted[i].length()-1);
    }
    lines.add(splitted);
}

//pretty much done, now convert List<String[]> to String[][]
String[][] result = new String[lines.size()][];
for(int i = 0; i<result.length; i++) {
    result[i] = lines.get(i);
}

System.out.println(Arrays.deepToString(result));

Output:

[[dog, runs, fast], [birds, flies, high], [baby, cries, often, in the evening], [He, works]]

If you need any of those characted that i "threw away", let me know in comment and i'll edit this answer.

Sign up to request clarification or add additional context in comments.

2 Comments

Your codes are working except I need to fix the following declaration since I'm still using Java7: List<String[]> lines = new ArrayList<String[]>(); However, I still need to get curly bracket outputs instead of list outputs. The reason is that I will later use the 2D array to get access to each elements and list doesn't seem to work: for (String[] sentence : result) { String subject= sentence[0]; String verb=sentence[1]; String object=sentence[2];...}
Never mind - the list working - it was the problem of my input text string format - many thanks!
1

Simply read the whole file at once in char [] and then convert it into string. Aftert that split the string at "\n" get a line and then again split the line ", ".I think this will do the charm.

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Fileto2darray {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        File file = new File("yourfilename.txt");
        FileReader fr = new FileReader(file);
        char temparr[] = new char[(int) file.length()];
        fr.read(temparr,0,(int) file.length());
        String [] tempstring = (new String(temparr)).split("\n");
        String array2d[][] = new String [tempstring.length][];
        for(int i=0 ; i<tempstring.length; i++)
        {
            array2d[i]=tempstring[i].split(", ");               
        }

    }

}

Comments

0

Leveraging Guava Tables:

  public static void main(final String... args) throws Exception {

        final String myString = "\"a\",\"b\",\"c\"\n" + "\"d\",\"e\",\"f\"\n";

        final File tempFile = File.createTempFile("myTempFile", ".txt");

        Files.append(myString, tempFile, Charset.defaultCharset());

        final List<String> stringsFromFile = Files.readLines(tempFile, Charset.defaultCharset());

        final Table<Integer, Integer, String> hashBasedTable = HashBasedTable.create();

        for (int row = 0; row < stringsFromFile.size(); row++) {

            final List<String> strings = Splitter.on(",")
                    .splitToList(stringsFromFile.get(row));

            for (int column = 0; column < strings.size(); column++) {
                hashBasedTable.put(row, column, strings.get(column));
            }
        }

        final String[][] stringArrayArray = ArrayTable.create(hashBasedTable)
            .toArray(String.class);

        // "a""b""c"
        // "d""e""f"
        for (int i = 0; i < stringArrayArray.length; i++) {

            final String[] row = stringArrayArray[i];

            for (int j = 0; j < row.length; j++) {
                System.out.print(row[j]);
            }

            System.out.println("");
        }
    }

Comments

0

Assuming there is a space after each char("a", "b", "c" and not "a","b","c") then something like that should do. I am using Scanner to read each line of the input and then process it word by word(with default delimiter). Then for each word i ad the second char(the char after " to a char array of size 3. Then i add this array to the 2d array.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;


public class CharArray {

    char[][] charArray = new char[100][3];
    int numOfElements = 0;

    private void testOutput(){
        for(int i = 0; i < numOfElements; i++){
            for(char c : charArray[i])
                System.out.print(c);
            System.out.println();
        }
    }

    private char[] processLine(Scanner lineScanner){
        char[] result = new char[3];
        for(int i = 0; i < 3; i++){
            result[i] = lineScanner.next().charAt(1);
        }
        return result;

    }


    private void convertToArray(){
        Scanner in = null;

        try {
            in = new Scanner(new FileInputStream("charsInput.txt"));//use w/e source for input  
        } catch (FileNotFoundException e) {
            System.exit(0);
            e.printStackTrace();
        }

        while(in.hasNextLine()){
            charArray[numOfElements] = processLine(new Scanner(in.nextLine()));
            numOfElements++;
        }

        testOutput();
    }

    public static void main(String[] args){
        new CharArray().convertToArray();

    }
}

The only problem is that my 2d array has size 100. If you don't know how many lines your input has you can read the input once to count how many lines it has and then read it again to process it.

For example something like that:

charArray = new char[countLines()][3];

private int countLines(){
    Scanner in = null;
    int counter = 0;
        try {
            in = new Scanner(new FileInputStream("charsInput.txt"));//use w/e source for input  
        } catch (FileNotFoundException e) {
            System.exit(0);
            e.printStackTrace();
        }

    while(in.hasNextLine())
        counter ++;

    return counter;

}

After that do what i mentioned earlier to parse the input. Hope his helps.

Comments

0

This looks like a job for regular expressions! I believe most file/line parsing should be done with REGEX.

^\s*(\"[a-z]\"),\s*(\"[a-z]\"),\s*(\"[a-z]\")\s*$

Regular expression visualization

Debuggex Demo

EDIT:

I did not realize you wanted more then just three inputs for each. I updated to reflect these revelations.

\s*(\"[a-z]+\")(?:,\s*|\s*$)

Regular expression visualization

Debuggex Demo

The idea:

It's pretty simple you will retrieve a String array when you read your file line by line. The array will contain 3 indices which will be associated with the capture groups labeled in my diagram. The string array you get should be then loaded into a list. Then you can offload it if you choose to a 2D array.

String[] s = {group1, group2, group3};

List<String[]> arrayList = new ArrayList<String[]>();
arrayList.add(s);

Note: If you need an example on how to implement a REGEX(regular expression) and how to parse them from their capture groups let me know.

2 Comments

IMO This will work only for 3 String (OP stresses he want arbitary numbers) any each string can only have one character? seem wierd to me.
@kajacx That makes the regex even easier. Ill update it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.