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));
Related
Basically, I had to create a scanner for a given file and read through the file (the name is input through the terminal by the user) once counting the number of lines in the file. Then after, I had to create an array of objects from the file, of the correct size (where the num of lines comes in). Then I had to create another scanner for the file and read through it again, storing it in the array I created. And lastly, had to return the array in the method.
My problem is I cannot seem to get the second scanner to actually store the file objects in the array.
I've tried using .nextLine inside a for loop that also calls the array, but it doesn't seem to be working.
public static Data[] getData(String filename) {
Scanner input = new Scanner(new File(filename));
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
System.out.println(count);
Data[] data = new Data[count];
Scanner input1 = new Scanner(new File(filename));
while (input1.hasNextLine()) {
for (int i = 0; i < count; i++) {
System.out.println(data[i].nextLine);
}
}
return data;
}
I expect the output to successfully read the input file so that it can be accessed by other methods that I have created (not shown).
You should definitely use an IDE if you don't have one, try intellij... There you have autocompletion and syntax checking and much more.
It is not clear what you want to do in your for loop, because there are several mistakes, for example the readline() function works only with the scanner objekt, so you can do input.nextline() or input1.nextline()`...
so I just show you, how you can get the Data from a file with Scanner:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Readfile {
public static void getData(String filename) throws FileNotFoundException {
ArrayList<String> test = new ArrayList<>(); //arraylist to store the data
Scanner inputSc = new Scanner(new File(filename)); //scanner of the file
while (inputSc.hasNextLine()) {
String str = inputSc.nextLine();
System.out.println(str); //print the line which was read from the file
test.add(str); //adds the line to the arraylist
//for you it would be something like data[i] = str; and i is a counter
}
inputSc.close();
}
public static void main(String[] args) {
try {
getData("/home/user/documents/bla.txt"); //path to file
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
You don't need to read thru the file twice - just use an ArrayList to hold the data that's coming in from the file, like this, and then return Data[] at the end:
public static Data[] getData(String filename) {
List<Data> result = new ArrayList<>();
try (Scanner input = new Scanner(new File(filename))){
while (input.hasNextLine()) {
Data data = new Data(input.nextLine());
result.add(data);
}
}
return result.toArray(new Data[0]);
}
Not clear what Data.class do you mean, if you switch it to String, the problem obviously would be in this line
System.out.println(data[i].nextLine);
if you want to assign and print simultaneously write this
for (int i = 0; i < count; i++) {
data[i] = input1.next();
System.out.println(data[i]);
}
and dont forget to close your Scanners, better use try-with-resources.
If your Data is your custom class you'd better learn about Serialization-Deserialization
Or use some ObjectMapper-s(Jackson, for example) to store your class instances and restore them.
Your way of opening the file just to count the lines and then again looping through its lines to store them in the array is not that efficient, but it could be just a school assignment.
Try this:
public static Data[] getData(String filename) {
Scanner input = null;
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
input.close();
System.out.println(count);
Data[] data = new Data[count];
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
for (int i = 0; i < count; i++) {
Data d = new Data(input.nextLine(), 0, 0);
data[i] = d;
System.out.println(data[i].name);
}
input.close();
return data;
}
After the 1st loop you must close the Scanner and reopen it so to start all over from the first line of the file.
I'm trying to to read the file contents into a character array using the scanner class and I keep getting a string index out of bounds error from my code and I'm not sure what's wrong
File fileName = null;
if(0<args.length) {
fileName = new File(args[0]);
}
Scanner s = null;
try {
s = new Scanner(fileName);
s.useDelimiter(",");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
char[]array = new char[26];
while(s.hasNext()) {
for(int i=0; i<27; i++) {
array[i] = s.next().charAt(i);
}
}
As far as I can tell, your code is equivalent to the following, which has no out of bounds exceptions
char[]array;
while(s.hasNext()) {
array = s.next().toCharArray();
}
However, after that while loop, your array will only equal the very last scanned value.
If you have individual comma separated characters, you can use the following. You do not need a loop within the existing loop
char[]array = new char[26];
int i = 0;
while(s.hasNext()) {
array[i++] = s.next().charAt(0);
}
In any case, I suggest using StringTokenizer rather than a Scanner
In your for loop, you are trying to access a[26] but you have declared memory for 26 characters. So you can access only a[0] to a[25].
I'm a beginner and need some help. I'm trying to scan a text file into an array line by line, but omitting one line. My text file is
i am
you are
he is
she is
it is
I want to create a method that will scan this and put elements into an array with an exception for one line (that is chosen by entering the String as a parameter for the method). Then erase the original text file and print there the created array (without that one deleted line). Sorry, I suck at explaining.
I have tried this:
public static void deleteLine(String name, String line) throws IOException {
String sc = System.getProperty("user.dir") + new File("").separator;
FileReader fr = new FileReader(sc + name + ".txt");
Scanner scan = new Scanner(fr);
int n = countLines(name); // a well working method returning the number if lines in the file (here 5)
String[] listArray = new String[n-1];
for (int i = 0; i < n-1; i++) {
if (scan.hasNextLine() && !scan.nextLine().equals(line))
listArray[i] = scan.nextLine();
else if (scan.hasNextLine() && scan.nextLine().equals(line))
i--;
else continue;
}
PrintWriter print = new PrintWriter(sc + name + ".txt");
print.write("");
for (int i = 0; i < n-2; i++) {
print.write(listArray[i] + "\n");
}
print.close()
}
I get an error "Line not found" when I enter: deleteLine("all_names","you are") (all_names is the name of the file). I'm sure the problem lies in the for-loop, but I have no idea why this doesn't work. :(
//SOLVED//
This code worked after all. Thanks for answers!
public static void deleteLine(String name, String line) throws IOException{
String sc = System.getProperty("user.dir") + new File("").separator;
FileReader fr = null;
fr = new FileReader(sc+name+".txt");
Scanner scan = new Scanner(fr);
int n = LineCounter(name);
String[] listArray = new String[n-1];
for (int i = 0; i < n-1; i++) {
if (scan.hasNextLine()) {
String nextLine = scan.nextLine();
if (!nextLine.equals(line)) {
listArray[i] = nextLine;
}
else i--;
}
}
PrintWriter print = new PrintWriter(sc+name+".txt");
print.write("");
for(int i=0;i<n-1;i++){
print.write(listArray[i]+System.lineSeparator());
}
print.close();
}
You are reading the lines twice scan.nextLine() while comparing and because of that you run out of the lines.
Replace your loop with this one or similar
for (int i = 0; i < n; i++) {
if (scan.hasNextLine()) {
String nextLine = scan.nextLine();
if (nextLine.equals(line)) {
listArray[i] = nextLine;
}
}
}
Have a look at how you are comparing String objects. You should use the equals method to compare a String's content. Using operators like == and != compares if the String objects are identical.
Now after using equals correctly have a look at how you are using nextLine. Check its Javadoc
I feel LineCounter(name) works because you did not put a ".txt" there. Try removing the ".txt" extension from the file name in the Filereader and Printwriter objects and see if it works. Usually in windows, the extension is not a part of the file name.
Here's an alternative (easier) solution to do what you want, using easier to understand code. (I think)
Also it avoids multiple
loops, but uses a single Java 8 stream to filter instead.
public static void deleteLine(String name, String line) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(name));
lines = lines.stream().filter(v -> !v.equals(line)).collect(Collectors.toList());
System.out.println(lines);
// if you want the String[] - but you don't need it
String[] linesAsStringArr = new String[lines.size()];
linesAsStringArr = lines.toArray(linesAsStringArr);
// write the file using our List<String>
Path out = Paths.get("output.txt"); // or another filename you dynamically create
Files.write(out, lines, Charset.forName("UTF-8"));
}
So I'm supposed to read in a .txt file and then write a new one with the numbers backwards. For some reason only the number 0 is being printed in the new file when it should be 987654321987654321.
EDIT:
The input file reads:
123456789123456789
import java.io.*;
import java.util.*;
class Reverb
{
public static void main(String[] args) throws IOException
{
//System.out.println("Enter the name of the file you wish to open and reverse.");
Scanner kb = new Scanner(System.in);
//String s = kb.next();
Scanner inFile = new Scanner(new File("Untitled.txt"));
PrintWriter outFile = new PrintWriter("reversamundo2.txt");
int[] a = new int[18];
int index = 0;
while(inFile.hasNextInt())
{
a[index] = inFile.nextInt();
index++;
}
for(int i = index; i >= 0; i--)
{
outFile.println(a[i]);
}
inFile.close();
outFile.close();
}
}
You want to read character by character instead of a string and then reverse it. You can just read the String and reverse it using StringBuilder. So the code looks like:
Scanner inFile = new Scanner(new File("Untitled.txt"));
PrintWriter outFile = new PrintWriter("reversamundo2.txt");
// Read the first String from the input file.
String line = inFile.next();
// Create a StringBuilder object for that string, reverse it and return a string.
String reverse = new StringBuilder(line).reverse().toString();
// Print the reversed string to a new file.
outFile.print(reverse);
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;
}
}