CSV data to 2d array java - java

Im probably going around this the wrong way, but My question is, how would I go about filling the array for fxRates?
CAD,EUR,GBP,USD
1.0,0.624514066,0.588714763,0.810307
1.601244959,1.0,0.942676548,1.2975
1.698615463,1.060809248,1.0,1.3764
1.234100162,0.772200772,.726532984,1.0
This is the information i have in the CSV file, I was thinking about using the scanner class to read it. Something like
private double[][] fxRates;
String delimiter = ","
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String line = sc.nextLine();
fxRates = line.split(delimiter)

Your way of solving this problem seems OK. But line.split(",") will return a 1D String array. You cannot assign it to fxRates. And also you should know the number of lines or rows in order to initialize fxRates at the beginning. Otherwise you should use a dynamic list structure like ArrayList.
Supposing you have 50 lines in your file, you can use something like:
private String[][] fxRates = String[50][];
String delimiter = ",";
Scanner sc = new Scanner(file);
int index=0;
while (sc.hasNextLine())
{
String line = sc.nextLine();
fxRates[index++] = line.split(delimiter)
}
And note that I've declared fxRates as a 2D String array, if you need double values you should do some conversion in place or later on.

import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;
public class CSVReader{
private String readFile(String path, Charset encoding) throws IOException
{
//Read in all bytes from a file at the specified path into a byte array
//This method will fail if there is no file to read at the specified path
byte[] encoded = Files.readAllBytes(Paths.get(path));
//Convert the array of bytes into a string.
return new String(encoded, encoding);
}
public String readFile(String path)
{
try {
//Read the contents of the file at the specified path into one long String
String content = readFile(path, Charset.defaultCharset());
//Display the string. Feel free to comment this line out.
System.out.println("File contents:\n"+content+"\n\n");
//Return the string to caller
return content;
}catch (IOException e){
//This code will only execute if we could not open a file
//Display the error message
System.out.println("Cannot read file "+path);
System.out.println("Make sure the file exists and the path is correct");
//Exit the program
System.exit(1);
}`enter code here`
return null;
}
}

The result of a split operation is a String array, not an array of double. So one step is missing: converting the Strings to doubles:
private double[][] fxRates = new double[maxLines][4];
String delimiter = ","
int line = 0;
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String line = sc.nextLine();
String[] fxRatesAsString = line.split(delimiter);
for (int i = 0; i < fxRatesAsString.length; i++) {
fxRates[line][i] = Double.parseDouble(fxRatesAsString[i]);
}

Another example;
Double[][] fxRates = new Double[4][];
String delimiter = ",";
//file code goes here
Scanner sc = new Scanner(file);
// Read File Line By Line
int auxI = 0;
// Read File Line By Line
for (int auxI =0; sc.hasNextLine(); auxI++) {
String line = sc.nextLine();
System.out.println(line);
String[] fxRatesAsString = line.split(delimiter);
Double[] fxRatesAsDouble = new Double[fxRatesAsString.length];
for (int i = 0; i < fxRatesAsString.length; i++) {
fxRatesAsDouble[i] = Double.parseDouble(fxRatesAsString[i]);
}
fxRates[auxI] = fxRatesAsDouble;
}
//to double check it
for (int y =0; y<fxRates.length; y++){
for (int x =0; x<fxRates.length; x++){
System.out.print(fxRates[y][x] +" ");
}
System.out.println("");
}

I wouldn't recommend you to parse CSVs in such a way, because Scanner is too low-level and raw solution for this. In comparison, DOM/SAX parsers are better to parse XML rather than regular expressions parsing or whatever that does not consider the document structure. There are CSV parsers that feature good APIs and suggest configuration options during a reader initialization. Just take a look at easy to use CsvReader. Here is a code sample using it:
package q12967756;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import static java.lang.Double.parseDouble;
import static java.lang.System.out;
import com.csvreader.CsvReader;
public final class Main {
private Main() {
}
private static final String MOCK =
"CAD,EUR,GBP,USD\n" +
"1.0,0.624514066,0.588714763,0.810307\n" +
"1.601244959,1.0,0.942676548,1.2975\n" +
"1.698615463,1.060809248,1.0,1.3764\n" +
"1.234100162,0.772200772,.726532984,1.0\n";
private static final char SEPARATOR = ',';
public static void main(String[] args) throws IOException {
// final FileReader contentReader = new FileReader("yourfile.csv");
final StringReader contentReader = new StringReader(MOCK);
final CsvReader csv = new CsvReader(contentReader, SEPARATOR);
csv.readHeaders(); // to skip `CAD,EUR,GBP,USD`
final Collection<double[]> temp = new ArrayList<double[]>();
while ( csv.readRecord() ) {
temp.add(parseRawValues(csv.getValues()));
}
final double[][] array2d = temp.toArray(new double[temp.size()][]);
out.println(array2d[3][1]);
}
private static double[] parseRawValues(String[] rawValues) {
final int length = rawValues.length;
final double[] values = new double[length];
for ( int i = 0; i < length; i++ ) {
values[i] = parseDouble(rawValues[i]);
}
return values;
}
}

Related

taking in input from a file in java

i cannot for the life of me seem to take in the contents of this file, i keep getting No such elements exception on line 25, all help appreciate. heres a link to the file link
heres my code
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class practiceFinal {
public static void main(String[] args) {
String fileName = args[0];
int length = fileLength(fileName);
int[] array = new int[length];
String[] list = new String[length];
arrayPopulate(array, list, fileName);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
}
public static int fileLength(String fileName) {
File file = new File(fileName);
Scanner fileScan = new Scanner(fileName);
int counter = 0;
while (fileScan.hasNext()) {
fileScan.next();
counter++;
}
return counter;
}
public static void arrayPopulate(int[] array, String[] list, String fileName) {
File file = new File(fileName);
Scanner fileScan = null;
try {
fileScan = new Scanner(file);
} catch (FileNotFoundException e) {
System.out.println("details: " + e.getMessage());
}
for (int i = 0; i < array.length; i++) {
array[i] = fileScan.nextInt();
list[i] = fileScan.next();
}
}
}
There are a few problems here. First of all you are using fileScan.next(); to try and get the length of a file. This is going to give you 2 times the length because you are counting each token fileScan.next() grabs which will be first the number and then the letter.
Length of lines is 144 but when you calculate it, it returns 288.
So use fileScan.nextLine();, now some people have mentioned this but your program is still not going to work correctly because you passed Scanner fileScan = new Scanner(fileName); // mistake passed fileName instead of file
Here are the changes I made inside the fileLength() method:
File file = new File(fileName);
Scanner fileScan = new Scanner(file); // mistake passed fileName instead of file, changed from Scanner fileScan = new Scanner(fileName)
while (fileScan.hasNextLine()) {
fileScan.nextLine(); // changed from fileScan.next()
counter++;
}
Your output looks like:
84c89C11w71h110B96d61H92d10B3p40c97G117X13....
When you are printing the results, change the print statements to
System.out.print(array[i]);
System.out.print(" " + list[i]);
System.out.println();
Output now looks like:
84 c
89 C
11 w
71 h
....
Instead of using int length = fileLength(fileName); to find the length, use int length = fileName.length();
From the format of your file and your current code, it looks like length represents the number of "words" in the file. In your loop, you need to advance i by 2 instead of 1, since it consumes two "words" per iteration. This also means that each array is twice as long as it should be. Instantiate them with length/2.
for (int i = 0; i < array.length; i += 2) {
array[i] = fileScan.nextInt();
list[i] = fileScan.next();
}
Alternately, you could make length represent the number of lines in the file. To do that, use hasNextLine() and nextLine() in your counting loop. Then leave all of the rest of your code as-is.
while (fileScan.hasNextLine()) {
fileScan.nextLine();
counter++;
}
Additionally, make sure your Scanner is passed the proper parameters. A String is valid, but not for File I/O. You would need to first create a File object using the fileName.
Scanner fileScan = new Scanner(new File(fileName));

Input a text file in a two dimensional array with doubles

I'm new in Java.
I want to input a text file and create from it a two dimensional array the input is
like this
12,242 323,2324
23,4434 23,4534
23,434 56,3434
....
34,434 43,3443
I have tried
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class InputText {
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
int i=0;
File file;
file = new File("file.txt");
Scanner read=new Scanner(file);
while (read.hasNextLine()) {
String line=read.nextLine();
System.out.println(line);
}
}
}
which gives me the input but I cannot insert this in an array I tried different ways like splitting it.
Any suggestions?
Sorry for not being clear. The input i mentioned is doubles seperated by spaces. Also the format i gave you is what i get after i run the part of the programm i wrote. What i see in the text file is the numbers seperated by spaces. I tried to implement your suggestion but nothing seemed to work. I'm really lost here....
If you want to split a line to two numbers you can use
string[] numbers = line.split("\\s+");
If you want to read a double with comma
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
...
double d1 = format.parse(numbers[0]).doubleValue();
double d2 = format.parse(numbers[1]).doubleValue();
Personally i prefer to use scanner. In that case create it with
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
Scanner scanner2 = new Scanner(scanner.nextLine()).useLocale(Locale.FRANCE);
if (!scanner2.hasNextDouble()){
System.out.println("Do not have a pair");
continue;
}
double d1 = scanner2.nextDouble();
if (!scanner2.hasNextDouble()){
System.out.println("Do not have a pair");
continue;
}
double d2 = scanner2.nextDouble();
//do something
}
After reading the line.. you will have to again split the string on ','. The split string need to be converted into interger. YOu can see as below:
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class InputText {
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
int i = 0;
File file;
file = new File("file.txt");
Scanner read = new Scanner(file);
while (read.hasNextLine()) {
String line = read.nextLine();
String[] numbers = line.split(",");
for (i = 0; i < numbers.lenght; i++) {
String numStr = numbers[i];
String x=numStr.replaceAll("\\s+",""); //eleminate the space in any.
Double num = Double.valueOf(x);
System.out.println(" num is: " + num); //Here you can store the number in array.
}
}
}
}
Try to use something like that(add also try catch statement)
String line = "";
br = new BufferedReader(new FileReader("file.txt"));
int i=0;
while ((line = br.readLine()) != null) {
// use comma as separator
String[] lineArray= line.split(",");
for(int j=0;j<lineArray.length;j++){
my2DArray[i][j] = lineArray[j];
}
i++;
}
for(int i=0;i<my2DArray[0].length;i++){
for(int j=0;j<my2DArray[1].length;j++){
System.out.print(my2DArray[i][j] + " ");
}
}

Using delimiter in java Scanner class to read a comma seperated file

I am trying to assign values in a file using a comma as a delimiter. The problem arises after the first line, because there is no comma at the end of the first line, so the Scanner is reading the last object of the first line and the first object of the second line as one single object. How do I tell the Scanner to only read the line?
The link to the file I am reading is: ftp://webftp.vancouver.ca/OpenData/csv/schools.csv
String schoolURL = ("ftp://webftp.vancouver.ca/OpenData/csv/schools.csv");
URL url = new URL(schoolURL);
Scanner sc2 = new Scanner(url.openStream()).useDelimiter(",");
//The file I am trying to read has a header line as the first line, hence the sc2.nextLine() being at the top of the for loop.//
for(int i=0; sc2.hasNextLine(); i++) {
sc2.nextLine();
String name, add, website;
double lat, longi;
name = sc2.next();
lat=Double.parseDouble(sc2.next());
longi=Double.parseDouble(sc2.next());
add=sc2.next();
website=sc2.next();
schools[i] = new School(name, lat, longi, add, website);
}
When it should be an implementation based on java.util.Scanner, you should make it to accept also the end of a line as another delimiter, in addition to comma.
If I get the Pattern definition right, the instantiation of Scanner should be:
Scanner sc2 = new Scanner( url.openStream() ).useDelimiter( ",|\\R" );
The \R stands for
Linebreak matcher: Any Unicode linebreak sequence, is equivalent to
\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
Refer to the documentation for java.util.regex.Pattern for the details.
Alternative way is use BufferedReader
As say #Yannis Rizos first read line then split it:
Java 7
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import static java.lang.Double.parseDouble;
public class App {
private static final String SOURCE_URL = "ftp://webftp.vancouver.ca/OpenData/csv/schools.csv";
private static final int SCHOOL = 0;
private static final int LATITUDE = 1;
private static final int LONGITUDE = 2;
private static final int ADDRESS = 3;
private static final int WEBSITE = 4;
public static void main(String[] args) {
boolean isHeader = true;
List<School> schools = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(SOURCE_URL).openStream()))) {
for (String line; (line = reader.readLine()) != null; ) {
if (isHeader) {
isHeader = false;
}
else {
String[] snippets = line.split(",");
// Class a School have next constructor signature
// public School(String name, double latitude, double longitude, String address, String webSite)
schools.add(new School(
snippets[SCHOOL],
parseDouble(snippets[LATITUDE]),
parseDouble(snippets[LONGITUDE]),
snippets[ADDRESS],
snippets[WEBSITE]
));
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Java 8
List<School> schools = Files.lines(Paths.get(SOURCE_URL))
.skip(1) // skip header
.map(line -> line.split(","))
.map(snippets -> new School(
snippets[SCHOOL],
parseDouble(snippets[LATITUDE]),
parseDouble(snippets[LONGITUDE]),
snippets[ADDRESS],
snippets[WEBSITE]
))
.collect(Collectors.toList());
As result you will have collections of 113 schools.

Reading a file in Java

I have the following code to open and read a file. I'm having trouble figuring out how I can have it go through and print the total number of each character in the file, print the first and last character, and print the character exactly in the middle of the file. What's the most efficient way to do this?
This is the main class:
import java.io.IOException;
public class fileData {
public static void main(String[ ] args) throws IOException {
String file_name = "/Users/JDB/NetBeansProjects/Program/src/1200.dna";
try {
ReadFile file = new ReadFile(file_name);
String[] arrayLines = file.OpenFile();
int i;
for (i=0; i<arrayLines.length; i++)
{
System.out.println(arrayLines[i]);
}
}
catch (IOException e) {
System.out.println(e.getMessage()) ;
}
}
}
and the other class:
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ReadFile {
private String path;
public ReadFile (String file_path)
{
path = file_path;
}
public String[] OpenFile() throws IOException
{
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
int i;
for(i=0; i<numberOfLines; i++)
{
textData[i] = textReader.readLine();
}
textReader.close();
return textData;
}
int readLines() throws IOException
{
FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);
String aLine;
int numberOfLines = 0;
while (( aLine = bf.readLine() ) != null)
{
numberOfLines++;
}
bf.close();
return numberOfLines;
}
Some hints which might help.
A Map can be used to store information about each character in the alphabet.
The middle of the file can be found from the size of the file.
These few lines of code will do it (using Apache's FileUtils library):
import org.apache.commons.io.FileUtils;
public static void main(String[] args) throws IOException {
String str = FileUtils.readFileToString(new File("myfile.txt"));
System.out.println("First: " + str.charAt(0));
System.out.println("Last: " + str.charAt(str.length() - 1));
System.out.println("Middle: " + str.charAt(str.length() / 2));
}
Anyone who says "you can't use libraries for homework" isn't being fair - in the real world we always use libraries in preference to reinventing the wheel.
The easiest way to understand I can think of is to read the entire file in as a String. Then use the methods on the String class to get the first, last, and middle character (character at index str.length()/2).
Since you are already reading in the file a line at a time, you can use a StringBuilder to construct a string out of those lines. Using the resulting String, the charAt() and substring() methods you should be able to get out everything you want.

how to read a txt file containing matrix form of data into 2d array of same dimensions as in the file using java

here is my code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class csvimport5 {
public static void main(String[] args) throws IOException {
double [][] data = new double [87][2];
File file = new File("buydata.txt");
int row = 0;
int col = 0;
BufferedReader bufRdr = new BufferedReader(new FileReader(file));
String line = null;
//read each line of text file
while((line = bufRdr.readLine()) != null && row < data.length)
{
StringTokenizer st = new StringTokenizer(line,",");
while (st.hasMoreTokens())
{
//get next token and store it in the array
data[row][col] = Double.parseDouble(st.nextToken());
col++;
}
col = 0;
row++;
}
System.out.println(" "+data[87][2]);
}
}
it shows error:-numberformatException :empty string
pls help me
At some point in your file, the st.nextToken() is returning an empty string. Because you're trying to parse that into a Double, you're getting an error (there are no numbers in an empty string to get a double from).
The most common reason for this is bad input data. Are you able to provide a subset of your buydata.txt file, which causes the bug to occur?
As suggested by Erica, the cause of the error is some badly formatted string in your input file, which cause parseDouble() to throw a NumberFormatException. You should sorround it into a try ... catch. You could something like this:
// set val to a constant value that you know is not acceptable
dobule val = UNACCEPTABLE_VALUE;
String token = st.nextToken();
try {
val = Double.parseDouble(st.nextToken());
} catch (NumberFormatException e) {
System.err.println("bad value: " + token + " at line: " + line);
}
data[row][col] = val;
col++

Categories

Resources