I am trying to get the values out of String[] value; into String lastName;, but I get errors and it says java.lang.ArrayIndexOutOfBoundsException: 2
at arduinojava.OpenFile.openCsv(OpenFile.java:51) (lastName = value[2];). Here is my code, but I am not sure if it is going wrong at the split() or declaring the variables or getting the data into another variable.
Also I am calling input.next(); three times for ignoring first row, because otherwise of study of Field of study would also be printed out..
The rows I am trying to share are in a .csv file:
University Firstname Lastname Field of study
Karlsruhe Jerone L Software Engineering
Amsterdam Shahin S Software Engineering
Mannheim Saman K Artificial Intelligence
Furtwangen Omid K Technical Computing
Esslingen Cherelle P Technical Computing
Here's my code:
// Declare Variable
JFileChooser fileChooser = new JFileChooser();
StringBuilder sb = new StringBuilder();
// StringBuilder data = new StringBuilder();
String data = "";
int rowCounter = 0;
String delimiter = ";";
String[] value;
String lastName = "";
/**
* Opencsv csv (comma-seperated values) reader
*/
public void openCsv() throws Exception {
if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
// Get file
File file = fileChooser.getSelectedFile();
// Create a scanner for the file
Scanner input = new Scanner(file);
// Ignore first row
input.next();
input.next();
input.next();
// Read from input
while (input.hasNext()) {
// Gets whole row
// data.append(rowCounter + " " + input.nextLine() + "\n");
data = input.nextLine();
// Split row data
value = data.split(String.valueOf(delimiter));
lastName = value[2];
rowCounter++;
System.out.println(rowCounter + " " + data + "Lastname: " + lastName);
}
input.close();
} else {
sb.append("No file was selected");
}
}
lines are separated by spaces not by semicolon as per your sample. Try in this way to split based on one or more spaces.
data.split("\\s+");
Change the delimiter as shown below:
String delimiter = "\\s+";
EDIT
The CSV file should be in this format. All the values should be enclosed inside double quotes and there should be a valid separator like comma,space,semicolon etc.
"University" "Firstname" "Lastname" "Field of study"
"Karlsruhe" "Jerone" "L" "Software Engineering"
"Amsterdam" "Shahin" "S" "Software Engineering"
Please check if you file is using delimiter as ';' if not add it and try it again, it should work!!
Use OpenCSV Library for read CSV files .Here is a detailed example on read/write CSV files using java by Viral Patel
Related
Hello I am having issues reading from csv file which contains 3 columns per row. I cant seem to parse the last cell (3) to an integer even though it is always a "parsable" string:
Berlin,Buenos Aires,7402 I can't seem to get 7402 all the compiler throws is:
"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:658)
at java.base/java.lang.Integer.parseInt(Integer.java:776)
This is the code I have:
Scanner scan = new Scanner("worldcities.csv");
scan.useDelimiter("[,\\n]"); // get everything before a comma or a newline
while(scan.hasNext()) { // while this file has something then we
edge.v1 = scan.next(); // take vertice1 ----> city 1
edge.v2 = scan.next(); //take vertice2 ----> city 2
edge.e = Integer.parseInt(scan.next()); // parse the third value as int(distance between city1 and city2)
minheap.add(edge);
}
scan.close();
I seem to be able to get the first 2 values fine in the debugger.
the console just shows "
You can iterate throught file lines with the nextLine() method, as in this example:
Scanner scanner = new Scanner(new File("worldcities.csv"));
while (scanner.hasNextLine()) {
String columns[] = scanner.nextLine().split(",");
edge.v1 = columns[0]; // take vertice1 ----> city 1
edge.v2 = columns[1]; //take vertice2 ----> city 2
edge.e = Integer.parseInt(columns[2]); // parse the third value as int(distance between city1 and city2)
minheap.add(edge);
}
scanner.close();
or with using the Files class without the Scanner:
List<String> rows = Files.readAllLines(Paths.get("worldcities.csv"));
for (String row : rows) {
String columns[] = row.split(",");
edge.v1 = columns[0]; // take vertice1 ----> city 1
edge.v2 = columns[1]; //take vertice2 ----> city 2
edge.e = Integer.parseInt(columns[2]); // parse the third value as int(distance between city1 and city2)
minheap.add(edge);
}
Also you can use a special library for working with CVS files, for example look at Apache Commons CSV library.
Every time I run it, gives this message (( InputMismatchException )) where is the problem from ?
File f = new File("nameList.txt");
try {
PrintWriter out;
out = new PrintWriter(f);
for (int i = 0; i < 4; i++) {
out.printf("Name : %s Age : %d ", "Rezaee-Hadi", 19);
out.println("");
}
out.close();
} catch (IOException ex) {
System.out.println("Exception thrown : " + ex);
}
try {
Scanner in = new Scanner(f);
String name = in.nextLine();
int age = in.nextInt();
for (int i = 0; i < 4; i++) {
System.out.println(name);
System.out.println(age);
}
in.close();
} catch (FileNotFoundException ex) {
System.out.println("Exception thrown : " + ex);
}
You are creating your data file in the following data format:
Name : Rezaee-Hadi Age : 19
Now, it really doesn't matter (to some extent) how you format your data file as long as you realize that you may need to parse that data later on. You really don't need to maintain a header with your data on each file line. We already know that the first piece of data on any file line is to be a Name and the second piece of data on any file line is to be the Age of the person the Name relates to. So, the following is sufficient:
Rezaee-Hadi, 19
If you want, you can place a header as the very first line of the data file so that it can easily be determined what each piece of data on each line relates to, for example:
Name, Age
Rezaee-Hadi, 19
Fred Flintstone, 32
Tom Jones, 66
John Smith, 54
This is actually a typical format for CSV data files.
Keeping with the file data format you are already using:
There is nothing wrong with using the Scanner#nextLine() method. It's a good way to go but you should be iterating through the file line by line using a while loop because you may not always know exactly how many actual data lines are contained within the file, for example:
Scanner in = new Scanner(f);
String dataLine;
while (in.hasNextLine()) {
dataLine = in.nextLine().trim();
// Skip Blank Lines
if (dataLine.equals("")) {
continue;
}
System.out.println(dataLine);
}
This will print all the data lines contained within your file. But this is not what you really want is it. You want to separate the name and age from each line which means then that you need to parse the data from each line. One way (in your case) would be something like this:
String dataLine;
Scanner in = new Scanner(f);
while (in.hasNextLine()) {
dataLine = in.nextLine().trim();
// Skip Blank Lines
if (dataLine.equals("")) {
continue;
}
String[] dataParts = dataLine.replace("Name : " , "").split(" Age : ");
System.out.println("The Person's Name: " + dataParts[0] + System.lineSeparator()
+ "The Person's Age: " + dataParts[1] + System.lineSeparator());
}
In the above code we iterate through the entire data file one line at a time using a while loop. As each line is read into the dataLine string variable it is also trimmed of any leading or trailing whitespaces. Normally we don't want these. We then check to make sure the line is not blank. We don't normally want these either and here we skip past those blank lines by issuing a continue to the while loop so as to immediately initiate another iteration. If the file line line actually contains data then it is held within the dataLine variable.
Now we want to parse that data so as to retrieve the Name and the Age and place them into a String Array. We do this by using the String#split() method but first we get rid of the "Name : " portion of the line using the String#replace() method since we don't want to deal with this text while we parse the line. In the String#split() method we supply a string delimiter to split by and that delimiter is " Age : ".
String[] dataParts = dataLine.replace("Name : " , "").split(" Age : ");
Now when each line is parsed, the Name and Age will be contained within the dataParts[] string array as elements located at index 0 and index 1. We now use these array elements to display the results to console window.
At this point the Age is a string located in the dataParts[] array at index 1 but you may want to convert this age to a Integer (int) type value. To do this you can utilize the Integer.parseInt() or Integer.valueOf() methods but before you do that you should validate the fact the the string you are about to pass to either of these methods is indeed a string numerical integer value. To do this you would utilize the String#matches() method along with a simple little Regular Expression (RegEx):
int age = 0;
if (dataParts[1].matches("\\d+")) {
age = Integer.parseInt(dataParts[1]);
// OR age = Integer.valueOf(dataParts[1]);
System.out.println("Age = " + age);
}
else {
System.out.println("Age is not a numerical value!");
}
The regular expression "\\d+" placed within the String#matches() method basically means, "Is the supplied string a string representation of a integer numerical value?". If the method finds that it is not then boolean false is returned. If it finds that the value supplied is a string integer numerical value then boolean true is returned. Doing things this way will prevent any NumberFormatException's from occurring.
Replace this:
int age=0;
while (in.hasNext()) {
// if the next is a Int,
// print found and the Int
if (in.hasNextInt()) {
age = in.nextInt();
System.out.println("Found Int value :"
+ age);
}
}
in place of this:
int age = in.nextInt();
Then you will not get "InputMismatchException" anymore..
I want to read data from text file in java, but text file doesn't contain any delimiter like space or comma after some text. Some guy told me that its possible via flatpack.
So how can I read text and parse it as delimited and stored them.
Eg of text file data
"Prod Name" "City" "Price" "zipcode" "Date"
samsungA London 65001402110/07/2018
samsungA California 35001202122/08/2018
samsungA Delhi 44001202112/08/2018
I want to store: as:
Name in string
City in string
Price in int
zipcode in int
date as date
Any view on how to achieve this?
You can do this with a simple file reader. Your file is delimited by spaces; each row ends with a newline character according to your example.
As such, you just need to do a bit of arithmetic to calculate the indexes as you have price, post code and date information in the third piece of each row.
public static void main(String...args) throws IOException {
final File file = new File("/home/william/test.txt");
final String delimiter = " ";
final int dateStrLen = 10;
final int postCodeLen = 6;
BufferedReader br = new BufferedReader(new FileReader(file));
String tmp;
while ((tmp = br.readLine()) != null) {
String[] values = tmp.split(delimiter);
String name = values[0];
String city = values[1];
int dateStartPos = values[2].length() - dateStrLen;
int postCodeStartPos = dateStartPos - postCodeLen;
String date = values[2].substring(dateStartPos);
String postCode = values[2].substring(postCodeStartPos, dateStartPos);
String price = values[2].substring(0, postCodeStartPos);
// do something with the data
// you could store it with a dto or in arrays, one for each "column"
System.out.println(String.format("name: %s; city: %s; price: %s; post-code: %s; date: %s", name, city, price, postCode, date));
}
}
I think that using a flatpack or not is not the problem.
If the file does not contain delimiters, then you should view the table as a file built by data-columns and read it with character position definition.
You should say then that at the start of the file you have position 0 and then the next character is position 1 and then 2 ... and so on.
Then all rows that have data between inclusive 0 and 7 characters wide is the "Prod Name" and will return samsungA.
From character 9 to 18 (assuming 18 is the maximum position) you should read records of "City".
So prerequisite is to know how many characters wide is each data column.
For example row 1 has "London" but then is "California" and you could have wider names. So you need to know or you need to find the maximum position that ends the data for each data-column.
And you can do it without flatpack.
Well you can use parser, and xml schema to define the length of the required variables that way one can extract the required varaibles. But yes, those variables will have predefined length.
String data= "samsungA500";
String schema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"<!-- DTD can be pulled from the Jar or over the web -->\r\n" +
"<!DOCTYPE PZMAP SYSTEM \"flatpack.dtd\" >\r\n" +
"<!--<!DOCTYPE PZMAP SYSTEM \"http://flatpack.sourceforge.net/flatpack.dtd\"> -->\r\n" +
"<PZMAP>\r\n" +
" <COLUMN name=\"std_name\" length=\"9\" />\r\n" +
" <COLUMN name=\"std_price\" length=\"3\" />\r\n" +
"</PZMAP>";
InputStream mapping = new ByteArrayInputStream(schema.getBytes());
InputStream dataStream = new ByteArrayInputStream(data.getBytes());
Parser pzparser = DefaultParserFactory.getInstance().newFixedLengthParser(mapping, dataStream);
DataSet ds = pzparser.parse();
while (ds.next()) {
System.out.println(ds.getString("std_name"));
System.out.println(ds.getInt("std_price"));
System.out.println(ds.getString("std_name"));
}
My code does read and write the file, but it is not on a new line for every value and instead prints every value in one line.
// 2 points
static void Q1(String inputFilename, String outputFilename) {
// You are given a csv file (inputFilename) with all the data on a single line. Separate the
// values by commas and write each value on a separate line in a new file (outputFilename)
String data = "";
try {
for(String s :Files.readAllLines(Paths.get(inputFilename))){
data = data + s;
}
Files.write(Paths.get(outputFilename), data.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
As such the grader says:
Incorrect on input: [data/oneLine0.csv, output0.txt]
Expected output : overwrought plastic bomb
wrapped litter basket
obstetric matter of law
diabetic stretching
spatial marathi
continental prescott
reproductive john henry o'hara
hollow beta blocker
stereotyped national aeronautics and space administration
irremediable st. olaf
brunet fibrosis
embarrassed dwarf elm
superficial harrier
disparaging whetstone
consecrate agony
impacted lampoon
nefarious textile
some other organisation
Your output : overwrought plastic bomb,wrapped litter basket,obstetric matter of law,diabetic stretching,spatial marathi,continental prescott,reproductive john henry o'hara,hollow beta blocker,stereotyped national aeronautics and space administration,irremediable st. olaf,brunet fibrosis,embarrassed dwarf elm,superficial harrier,disparaging whetstone,consecrate agony,impacted lampoon,nefarious textile,some other organisation
String data = "";
try {
// input file has all data on one line, for loop isn't necessary here
// input file has elements separated by comma characters
for(String s : Files.readAllLines(Paths.get(inputFilename))){
data = data + s;
}
String[] separated = data.split(",");// does not handle embedded commas well
data = "";
// output file should have each comma separated value on its own line
for (String t : separated) {
data = data + t + System.getProperty("line.separator");
}
Files.write(Paths.get(outputFilename), data.getBytes());
}
First of all, you need to remove the comma from the CSV file. I'd suggest using
s = s.replace(",",""); Additionally, you must append a \n to each string to make it appear on a new line. So, you should add s += "\n"; This yields the code:
// 2 points
static void Q1(String inputFilename, String outputFilename) {
// You are given a csv file (inputFilename) with all the data on a single line. Separate the
// values by commas and write each value on a separate line in a new file (outputFilename)
String data = "";
try {
for(String s :Files.readAllLines(Paths.get(inputFilename))){
s.replace(",","");
s += "\n";
data = data + s;
}
Files.write(Paths.get(outputFilename), data.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
I have text file in which I have following content.
Name Sahar Hassan
Age 26
I have wrote a Java code to find the location of the word "Name" and it works fine. I want to output the string right after the word "Name", that is "Sahar Hassan".
Keep it simple:
import java.io.*;
import java.util.Scanner;
File file = new File("somefilepath");
Scanner s = new Scanner(file);
String name = null;
while (s.hasNextLine()) {
String line = s.nextLine();
if (line.startsWith("Name"))
name = line.substring(5);
}
// The variable "name" will be the name you seek (or be null if line not found)
You could use indexOf and search for the newline character (starting from the index of Name). Like this:
String str = "Name Sahar Hassan\nAge 26";
int nameIndex = str.indexOf("Name"); // What you say you already have.
int newLineIndex = str.indexOf("\n", nameIndex);
// Extract part after "Name"
String name = str.substring(nameIndex + 5, newLineIndex);
System.out.println(name); // Prints "Sahar Hassan"