CSV input to two dimmensional array in java - java

I have a read() method and inside I want to separate the Strings(which have spaces between them) and putting them in a two dimensional array, but before that I get rid of all the spaces. After the array initialized, it is given to the CSV constructor and that is creating its own 2D array.
The problem is that I always get the following error: "variable sr might not have been initialized" at CSV csv = new CSV(sr).
How do I make sure that my array gets the valid String?
private String[][] tomb;
private CSV(String[][] t2) {
tomb = new String[t2.length][];
for(int i = 0; i < t2.length; i++) {
tomb[i] = new String[t2[i].length];
for(int j = 0; j < t2[i].length; j++) {
tomb[i][j] = t2[i][j];
}
}
}
public static CSV read(Scanner sc) {
String[][] sr;
int n = 0;
while (sc.hasNextLine())
{
String line = sc.nextLine();
String[] str = line.split(",");
sr = new String[str.length][];
for (int i = 0; i < str.length; i++) {
sr[i][n].replaceAll("\\s+","");
}
n++;
}
CSV csv = new CSV(sr);
return csv;
}

You can resolve the error by setting sr to null in the initialization:
String[][] sr = null;
If you want to make sure sr was set correctly, you can check if sr is still null after the while loop completes.

Related

Search a 2D Array for a string of another 1D Array and then put them in a new 2D with the sorting of the 1D

This title must be really confusing, so let me explain my problem.
I have a one-dimensional Array (let's call it "ids") which is sorted in the way I need it to be.
Then, I have another 2D Array which contains a name on position 0 and an id in position 1 (let's call it "names").
So names[0][0] = name, names[0][1] = id.
Let me clarify that the 2 arrays are not of the same length!
What I want to do it so create a new 2D Array which has a name and an ID, but sorted like my one dimensional array (the ids are in the same order like they are there).
What I've tried so far is this (and all I am getting is a text file full of nulls):
for (int i = 0; i < ids.length; i++){
String equal = ids[i];
for (int j = 0; i < users.length; i++) {
if(users[j][1].equals(equal)) {
sortedArray[i][0] = users[j][0];
sortedArray[i][1] = equal;
}
}
}
for (int i=0; i<sortedArray.length; i++){
writer.println(sortedArray[i][0]+"\t"+sortedArray[i][1]);
}
It might not be of any use, but since I am creating these by reading files, this is the rest of my code:
BufferedReader reader;
BufferedReader reader2;
PrintWriter writer;
String[][] users = new String[39431][2];
String[] ids = new String[22890];
String[][] sortedArray = new String[22890][2];
reader = new BufferedReader(new FileReader("allConnectedUsers.txt"));
reader2 = new BufferedReader(new FileReader("ids.txt"));
String sorted = "sortedNamesWithIDs.txt";
writer = new PrintWriter(sorted, "UTF-8");
String usersline = reader.readLine();
String idsline = reader2.readLine();
for (int i = 0; i < users.length; i++) {
String splittedLine[] = usersline.split(" ");
String name = splittedLine[0];
String id = splittedLine[1];
users[i][0] = name;
users[i][1] = id;
usersline = reader.readLine();
}
for (int i = 0; i < ids.length; i++) {
String onlyIDs;
onlyIDs = idsline;
ids[i] = onlyIDs;
idsline = reader2.readLine();
}
I actually fixed it. It was a pretty dumb mistake.
In the nested loop, I wasn't checking for "j" or increasing it, but i.
Sorry for this dumb mistake, thanks if you even read it.

Filling a 2d character array from a file in java

I'm a beginner in java and I am trying to fill a 2d character array from an input file. To do this I constructed a method which takes in a 2d character array as a parameter variable, then reads the file and stores it as a character array. So far I have done everything except fill the array, as when I run the code the program throws a NoSuchElement exception. If anyone could help me with this I would greatly appreciate it.
public static char [][] MakeWordArray (char [][] givenArray)
{
try
{
File wordFile= new File ("words.txt");
Scanner in= new Scanner (wordFile);
int rows =0;
int col=0;
while (in.hasNextLine())
{
rows = rows + 1;
col = col + 1;
in.next();
}
char [][] words = new char [rows][col];
File wordFile2= new File ("words.txt");
Scanner in2= new Scanner(wordFile2);
for ( int i = 0; i < rows; i++)
{
for (int j = 0; j < col; j++)
{
String wordly = in2.nextLine();
words [i][j] = wordly.charAt(i);
}
}
return words;
}
catch (FileNotFoundException e)
{
System.out.println("File Does Not Exist");
}
return null;
}
I think your counting methods have some problems.
If you want to count how many lines your .txt have:
int counter = 0;
while (in.hasNextLine())
{
counter++;
in.nextLine();
}
If you want to count how many char your .txt have:
int counterWithoutSpace = 0, counterWithSpace = 0;
while (in.hasNextLine())
{
String line = in.nextLine();
Scanner inLine = new Scanner(line);
while (inLine.hasNext())
{
String nextWord = inLine.next();
counterWithoutSpace += nextWord.length();
counterWithSpace += nextWord.length() + 1;
}
counterWithSpace--;
}
If you want to count how many char you have on each line, I recommend ArrayList. Because the size of your array is dynamic.
Note that you can also you can use the char counter logic above with List too.See as follows:
List<Integer> arr = new ArrayList<Integer>();
while (in.hasNextLine())
{
arr.add(in.nextLine().length());
}
And if you realy needs the static array, you can use:
Integer[] intArr = arr.toArray(new Integer[0]);
You can transform its entire function as below to get a list of every Character of the .txt:
List<Character> arr = new ArrayList<Character>();
while (in.hasNextLine())
{
String line = in.nextLine();
for (char c : line.toCharArray())
{
arr.add(c);
}
}
Try using a do while loop instead of the while
do
{
rows=rows+1;
col=lol+1;
in.next();
}
while(in.hasNext());
There are multiple questions here.
1) Why did you provide a char[][] parameter when you are not even using it?
2) Why are you using two files when all you need to do is read from a file and convert it in 2d Array?
3) The method name should follow camel casing convention.
From what i understood from your question, This is a code i've tried.
NOTE- because the requirement is of an Array and not dynamic datatypes like List ArrayList etc., the data entered into char array might be lost
Saying that here is what works.
public class StackOverflow{
public static char [][] makeWordArray ()
{
try{
File f = new File("C:\\docs\\mytextfile.txt");
Scanner scan = new Scanner(f);
int row = 0, col = 0;
String readData = "";
while(scan.hasNextLine()){
readData += scan.nextLine();
row++;
}
double range = (readData.length()/row);
col = (int)Math.ceil(range);
char[][] arr = new char[row][col];
int count = 0;
for (int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
arr[i][j] = readData.charAt(count++);
System.out.println("Pos: ["+ i +"][" + j + "]" + arr[i][j]);
}
}
return arr;
}
catch(FileNotFoundException fe){
System.err.println(fe.getMessage());
return null;
}
}
public static void main(String[] arg){
char[][] myarr = StackOverflow.makeWordArray();
//print your array
}
}

null pointer exception string builder

I am trying to use the setCharAt method in a StringBuilder but I am getting a null pointer exception. Is there a way I can add values to the StringBuilder array I have made so I wont get these error.
From research I have found the .append() method but I'm not even sure how it works.
import java.util.*; // Allows for the input of a scanner method.
import java.io.*; // Allows for the inputting and outputting of a data file.
import java.lang.*; // Allows for the use of String Methods.
//////////////////////////////////////////////////////////////////////////////////////
public class TESTY
{
static Scanner testanswers;
static PrintWriter testresults;
public static void main(String[] args) throws IOException
{
testanswers = new Scanner(new FileReader("TestInput.dat"));
testresults = new PrintWriter("TestOutput.dat");
String StudentID;
String answers;
// Reads first two lines first to know how many records there are.
String answerKey = testanswers.nextLine();
int count = Integer.parseInt(testanswers.nextLine());
// Allocate the array for the size needed.
String[][] answerArray = new String[count][];
for (int i = 0; i < count; i++)
{
String line = testanswers.nextLine();
answerArray[i] = line.split(" ", 2);
}
for(int row = 0; row < answerArray.length; row++)
{
for(int col = 0; col < answerArray[row].length; col++)
{
System.out.print(answerArray[row][col] + " ");
}
System.out.println();
}
gradeData(answerArray, answerKey);
testanswers.close();
testresults.close();
}
///////////////////////////////////////////////////////////
//Method: gradeData
//Description: This method will grade testanswers showing
//what was missed, skipped, letter grade, and percentage.
///////////////////////////////////////////////////////////
public static double gradeData(String[][] answerArray, String answerKey)
{
String key = answerKey;
double Points = 0;
StringBuilder[] wrongAnswers = new StringBuilder[5];
String studAnswers;
for(int rowIndex = 0; rowIndex < answerArray.length; rowIndex++) /// Counting rows
{
studAnswers = answerArray[rowIndex][1].replace(" ", "S"); ///Counts rows, Col stay static index 1
for(int charIndex = 0; charIndex < studAnswers.length(); charIndex++)
{
if(studAnswers.charAt(charIndex) == key.charAt(charIndex))
{
Points += 2;
}
else if(studAnswers.charAt(charIndex) == 'S')
{
Points --;
}
else if(studAnswers.charAt(charIndex) != key.charAt(charIndex))
{
for(int i = 0; i < wrongAnswers.length; i++)
{
wrongAnswers[i].setCharAt(charIndex, 'X');
}
Points -= 2;
}
}
System.out.println(Points);
}
return Points;
}
}
The error is occurring on line 91 :
wrongAnswers[i].setCharAt(charIndex, 'X');
You have declared an array of StringBuilders, but you haven't initialized any of the slots, so they're still null.
Initialize them:
StringBuilder[] wrongAnswers = new StringBuilder[5];
for (int i = 0; i < wrongAnswers.length; i++)
{
wrongAnswers[i] = new StringBuilder();
}
Additionally, using setCharAt won't work here, because initially, there is nothing in the StringBuilder. Depending on what you want here, you may need to just call append, or you may initially want a string full of spaces so that you can set a specific character to 'X'.
StringBuilder[] wrongAnswers = new StringBuilder[5];
does not create 5 empty StringBuilders but 5 null StringBuilders.
You need to call something like
wrongAnswers[i] = new StringBuilder()
in order to initialize your 5 array members.
Your problem is that
StringBuilder[] wrongAnswers = new StringBuilder[5];
does not create 5 StringBuilder objects. It only creates an array with 5 null StringBuilder references. You need to create each StringBuilder separately with a line such as
wrongAnswers[i] = new StringBuilder();
inside a loop over i.

extract data from csv file and put to 2D Array - refactoring

I need read data from csv file and much more convinience for me is put there to 2D array (to my mind it's easiest way to work with this "schedule" data).
Each file line contained information in following format:
Instructor, Course, Group, Student, Result
as follows example:
Paul Schwartz,Introduction to Computer Architecture,I1,Ben Dunkin,88
Muhamed Olji,Object Oriented Programming,I4,Mike Brown,73
But my code needs some simplify. But I don't know how to make it easier and ask of You.
Code:
private String[][] fileContent(String pathToCSVFile) {
final int ROWS = 100;
final int COLUMNS = 5;
String fileData[][] = new String[ROWS][COLUMNS];
Scanner scanner = new Scanner(pathToCSVFile);
boolean done = false;
int i, j;
while (!done) {
for (i = 0; i >= 0; i++) {
for (j = 0; j >= 0; j++) {
String str[] = scanner.nextLine().split(",");
for (int element = 0; element < str.length; element++) {
fileData[i][element] = str[element];
if (i >= ROWS) {
Arrays.copyOf(fileData, fileData.length * 2);
}
}
}
}
if (!scanner.hasNextLine()) done = true;
}
return fileData;
}
How to refactor this snippet of code for better simplicity?
Does exist any better way for partially filled array (than Arrays.copyOf(fileData, fileData.length * 2))?
Using openCSV, you can get a list containing all the lines and convert it to an array (or just keep the list):
try (CSVReader reader = new CSVReader(new BufferedReader(
new FileReader(pathToCSVFile)));) {
List<String[]> lines = reader.readAll();
return lines.toArray(new String[lines.size()][]);
}
(using Java 7 try-with-resources syntax)
First of all, be careful with those for loops. They are "almost" undefined loops, because they start with i,j=0, and loop while >=0 (always, until they overflow into a negative number).
And why do you need them anyway? I think with you while and the for(element) you are done, right?
Something like that (I didn't tried, is just to explain the concept)
private String[][] fileContent(String pathToCSVFile) {
final int ROWS = 100;
final int COLUMNS = 5;
String fileData[][] = new String[ROWS][COLUMNS];
Scanner scanner = new Scanner(pathToCSVFile);
boolean done = false;
int i=0;
while (!done) {
String str[] = scanner.nextLine().split(",");
for (int element = 0; element < str.length; element++) {
fileData[i][element] = str[element];
if (i >= ROWS) {
Arrays.copyOf(fileData, fileData.length * 2);
}
}
if (!scanner.hasNextLine())
done = true;
else
i++;
}
return fileData;
}
By the way, why don't you use objects, like an ArrayList? It would make your life easier, so you don't have to worry about memory handling. You just add new objects.
Something like an ArrayList <ArrayList <String>>

Importing CSV file into 2D String array

I have to read a text file into a 2d Array.
The only problem I am having, is the width of the array varies, with a maximum size of 9 columns.
I don't know how many rows there will be.
Some lines will have 6 columns for example, and some will have 9.
here is a small section of my CSV file:
1908,Souths,Easts,Souths,Cumberland,Y,14,12,4000
1909,Souths,Balmain,Souths,Wests,N
1910,Newtown,Souths,Newtown,Wests,Y,4,4,14000
1911,Easts,Glebe,Glebe,Balmain,Y,11,8,20000
1912,Easts,Glebe,Easts,Wests,N
1913,Easts,Newtown,Easts,Wests,N
and here is my code so far
import java.io.*;
import java.util.*;
public class ass2 {
public static void main(String[] args) throws IOException {
readData();
}
public static void readData() throws IOException{
BufferedReader dataBR = new BufferedReader(new FileReader(new File("nrldata.txt")));
String line = "";
ArrayList<String[]> dataArr = new ArrayList<String[]>(); //An ArrayList is used because I don't know how many records are in the file.
while ((line = dataBR.readLine()) != null) { // Read a single line from the file until there are no more lines to read
String[] club = new String[9]; // Each club has 3 fields, so we need room for the 3 tokens.
for (int i = 0; i < 9; i++) { // For each token in the line that we've read:
String[] value = line.split(",", 9);
club[i] = value[i]; // Place the token into the 'i'th "column"
}
dataArr.add(club); // Add the "club" info to the list of clubs.
}
for (int i = 0; i < dataArr.size(); i++) {
for (int x = 0; x < dataArr.get(i).length; x++) {
System.out.printf("dataArr[%d][%d]: ", i, x);
System.out.println(dataArr.get(i)[x]);
}
}
}
The error I get is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at ass2.readData(ass2.java:23)
at ass2.main(ass2.java:7)
Can someone please help :'(
Thank you!
You can use OpenCSV for read the CSV file.
// Read all
CSVReader csvReader = new CSVReader(new FileReader(new File("nrldata.txt")));
List<String[]> list = csvReader.readAll();
// Convert to 2D array
String[][] dataArr = new String[list.size()][];
dataArr = list.toArray(dataArr);
The problem is with your inner loop. You are trying to access 9 elements of value regardless of how many values there are on the line. First, you should move the assignment to value to be before the inner loop. Then, you need to limit the loop iterations to the minimum of 9 and the length of value:
String[] value = line.split(",", 9);
int n = Math.min(value.length, data.length);
for (int i = 0; i < n; i++) { // For each token in the line that we've read:
data[i] = value[i]; // Place the token into the 'i'th "column"
}
Note that the trailing elements of data will be null.
You get the error, because you try to access a 7th token (index 6) on a line that contains only 6. Replace that:
for (int i = 0; i < 9; i++) { // For each token in the line that we've read:
String[] value = line.split(",", 9);
data[i] = value[i]; // Place the token into the 'i'th "column"
}
with this:
String[] value = line.spkit(",", 9); // Split the line into max. 9 tokens
for (int i = 0; i < value.length; i++) {
data[i] = value[i]; // Add each token to data[]
}
You could, in fact, replace the whole while-loop body with this one-liner:
dataArr.add(Arrays.copyOf(line.split(",", 9), 9));
See, also, this short demo.
Instead of array, you can use ArrayList of List. As List is dynamically growable so you do't need to think of it size either.
List<List<String>> dataArr = new ArrayList<List<String>>();
and
while ((line = dataBR.readLine()) != null){
for (int i = 0; i < 9; i++)
dataArr.add(Arrays.asList(line.split(",", 9)));
}

Categories

Resources