I am new to java and I am trying to do an assignment where I have to read in data from a text file where the text file has the total number of items in the lists in the first line and the height, weight and the name data in the following. Since there are 5 data points, the first integer in the file is '5' and the following 5 lines are the respective datas that I am scanning.
it seems like I have trouble running this code from the command line but I can run it from netbeans. I am getting the following exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundExceptions:0 at bmi.Bmi.main<Bmi.java:18>
Code
public static void main(String[] args) {
System.out.println("\nBMI Report:");
File file = new File (args [0]);
try{
Scanner scanner = new Scanner(new FileInputStream(file));
int count=scanner.nextInt();
for(int i=0;i<5;i++){
int height=scanner.nextInt();
int weight=scanner.nextInt();
String name=scanner.nextLine();
Exception in thread "main" java.lang.ArrayIndexOutOfBoundExceptions:0 at bmi.Bmi.main
This message means that element 0 was accessed, going beyond the bounds of the array, in other words the array is empty so this doesn't work.
This must be the problematic line in your pasted code:
File file = new File (args [0]);
If args is empty, that will raise the exception as in your post. Your program requires an argument. Of you pass it an argument, that should resolve your problem.
You might want to add a check first and print a helpful message, for example:
if (args.length < 1) {
System.out.println("You need to specify an argument. Bye.");
System.exit(1);
}
File file = new File (args [0]);
// ...
Related
This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 3 months ago.
I am currently learning Java and received the following task, that I cannot seem to solve:
"Create a Java program that prints one random poem of 5 lines in the console. The poems must be read from a text file."
I have copied 10 different poems inside a text file, all written underneath each other. I managed to make the program print out the very first poem (first 5 lines) in the console, but first of all, I am not sure if it's the correct way to do such, and I don't know how to make the program print out one random poem (5 lines that belong together) each time I run it.
Here is the farthest I could get:
public static void main(String[] args) throws IOException {
File file = new File("src/main/java/org/example/text.txt");
Scanner scanner = null;
try {
scanner = new Scanner(file);
int i = 0;
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (i < 5) {
i++;
System.out.println(line);
}
}
} catch (Exception e) {
}
}
You can try
private static final int POEM_LINES_LENGTH = 5;
public static void main(String[] args) throws IOException
{
// The file
File file = new File("src/main/java/org/example/text.txt");
// Get all the lines into a single list
List<String> lines = Files.readAllLines(Paths.get(file.getAbsolutePath()));
// Get a random poem and point at the end.
int poemFinish = new Random().nextInt(lines.size() / POEM_LINES_LENGTH) * POEM_LINES_LENGTH;
// Point to the be start
int start = poemFinish - POEM_LINES_LENGTH;
// Create a sublist with the start and finish indexes.
for (String line : lines.subList(start, poemFinish))
System.out.println(line);
}
This will not read the entire file into the memory, hence large files can also be read.
final int totalPoems = 17;
int skip = new Random().nextInt(totalPoems) * 5;
Path path = Paths.get("file.txt");
BufferedReader reader = Files.newBufferedReader(path);
while(skip-->0){
reader.readLine();
}
for(int i=0; i<5; i++){
System.out.println(reader.readLine());
}
The downside is you have to know how many poems are in the file beforehand. If you don't want to do this you can quickly count the total number of lines/poems only one time.
I am getting error while taking input with Integer.parseInt(args[0]); error is in args section i know i can change it to scanner but i want to know this method.
Can anybody point out or show the solution to my problem?
class NegativeOutputException extends Exception{
private final int ex;
NegativeOutputException(int a){
ex = a;
}
public String toString(){
return "NegativeOutputException!("+ex+")";
}
}
public class practice6_creating_custom_exception {
public static void main(String args[]){
int x = Integer.parseInt(args[0]);//Error Here argument at position one
int y = Integer.parseInt(args[1]);//argument at position two
//argument at position twenty one which doesn't exsist
int a;
try{
a = x * y;
if(a < 0)
throw new NegativeOutputException(a);
System.out.println("Output >>" + a);
}
catch(NegativeOutputException e){
System.out.println("Caught >>" + e);
}
}
}
Output::
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at practice6_creating_custom_exception.main(practice6_creating_custom_exception.java:21)
Process finished with exit code 1
It gives you a java. lang.ArrayIndexOutOfBoundsException because you are trying to access a position in an empty array.
parseInt() is not used for taking inputs in such a case you need to use Scanner
For your case, you need first take input (by using Scanner) and then assign it to an integer variable, directly parsing the argument array will not provide the input.
Scanner sc = new Scanner();
int x = sc.nextInt(); //Scans the next token of the input as an int
parseInt() function -
The parseInt() method parses a value as a string and returns the first integer.
Source
Scanner Class -
Scanner object holds the address of InputStream object present in the
System class. Input Stream object of system class reads data from the
keyboard which is byte stream/byte form. The Scanner class converts
this read byte into a specific data type.
Source
The parseInt() function cannot read data from the input stream which is byte stream/byte form, hence you cannot directly parse the args[] array and assign it to an integer variable as it is empty since it is not yet scanned.
If you are looking for different ways of taking input in Java then here they are:
Using Buffer Reader Class,
Using Scanner Class,
Using Console Class,
Using Command Line Argument,
Source
Most probably you are simply not passing any arguments.
One way to pass arguments to the main method in Java is with the command to run the application in terminal. You can simply add the arguments after the java command to run the application separating them with a space. If you want the user to input the data, then you should use Scanner instead.
In your case, navigate to the folder where your java file sits and run the following:
java practice6_creating_custom_exception 0 1
In this example, 0 and 1 are the arguments you are passing.
If you are using an IDE then this can usually be done in the run configurations.
Side note, you might need to compile the application before running it and the command for that is the following:
javac practice6_creating_custom_exception.java
String path1, path2;
int count = 0, i = 0;
path1 = args[0];
File file = new File(path1);
FileReader reader = new FileReader(file);
Scanner inputFile = new Scanner(reader);
while(inputFile.hasNextInt()) {
inputFile.nextLine();
count++;
}
int[] array1 = new int[count];
while(inputFile.hasNextInt()) {
//inputFile.nextLine();
array1[i] = inputFile.nextInt();
i++;
}
I never had this issue before, but when I try to write values to an array from a text file containing only int values, one per line, my array only returns all "0"s. instead of the numbers in the text file. I'm not sure if it has to do with me using the command line, but it has the correct argument (file destination) entered in my IDE.
Thanks in advance!
Notice that the exit condition of both while loops are the same. If the first ends then the second one will be jumped over as the condition is immediately false. The pointer of the scanner is already at the end of the file (all numbers have been read by the first loop) so there is nothing left to read.
You have 2 options to fix this issue.
Use an ArrayList: Use an ArrayList<int> object to save the numbers in the first loop. The list grows as numbers are entered so you don't need to know the number of lines before making this object, as opposed to needing to know this to make an array.
Scan the file again: In between the loops close the previous filereader and scanner and create a new one. This new scanner will point to the start of the file again and the second loop will run smoothly.
I'm creating this code where a scanner should scan every word in the text file and then proceed to save each and every one of them in a specific array. But every time the scanner starts to scan it only reaches the next line and stops at the first word. I don't know what is causing this exactly. I'm using a delimiter where it separates words between commas ",".
Here is the piece of code:
package ex13a;
import java.util.Scanner;
import java.io.*;
/**
*
* #author Work
*/
public class Ex13a {
static Scanner scan = new Scanner(System.in);
static int[] number = new int[100];
static String[] f_users = new String[100];
static String[] l_users = new String[100];
static String[] passwd = new String[100];
static int i = 0;
static String fullName;
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
String path = "C:\\Users\\Work\\Desktop\\users.txt";
File inFile = new File(path);
Scanner inPut = new Scanner(inFile).useDelimiter(",");
Scanner inPut2 = new Scanner(inFile);
while(inPut.hasNext()){
System.out.println(number[i] = inPut.nextInt());
System.out.println(f_users[i] = inPut.next());
System.out.println(l_users[i] = inPut.next());
System.out.println(passwd[i] = inPut.next());
i++;
}
It throws me that error:
1
Ahmed
Dhaif
asdf56
Exception in thread "main" java.util.InputMismatchException
2
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at ex13a.Ex13a.main(Ex13a.java:32)
C:\Users\Work\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
Grab line by line, then split the lines around the comma, then parse the strings returned.
Scanner inPut = new Scanner(inFile);
while(inPut.hasNextLine()){
String [] data = inPut.nextLine().split(",");
System.out.println(Integer.parseInt(data[0]));
number[i] = Integer.parseInt(data[0]); //to add to your arrays
System.out.println(Integer.parseInt(data[1]));
System.out.println(Integer.parseInt(data[2]));
System.out.println(Integer.parseInt(data[3]));
i++;
}
Note you should check that the array is the correct size and the string is actually an Integer. You should be able to do that. But this should get you started.
If you are going to store the values in a data structure, use something dynamic and not a data structure of fixed length like an array.
Read the error message. The exception was raised in the nextInt() method. From the documentation, for nextInt()
InputMismatchException - if the next token does not match the Integer
regular expression, or is out of range
So the token you're reading isn't what you think it is. You could replace the nextInt() call with something else to see what it is, and go from there.
For the record, this code is remarkably trusting
The loop checks for "is there any token", and then assumes it is an
integer.
You assume that if there is 1 token, there will be 3 more after that each loop iteration.
There is no protection for the number of entries, you assume it will be <=100
Edit
My guess is there is something about the end-of-line that isn't printable, so when you read it it looks like an integer, but actually is something like ^r###, where "^r" is a control code and ### are digits.
I bet if you change the hasNext() to hasNextInt() it will just stop after processing 1 line. Read the file with a binary editor to see what you're really reading.
This question already has answers here:
How to get around the command line length limit?
(9 answers)
Closed 9 years ago.
I am writing a code that accepts a list of files as an input. I am doing stress testing and an error occurs if there are a lot of files as an input.
My main function accepts an array of Strings as an input.
public static void main(String[] args)
I have around 200 files as an input. My args accepts input in this format:
-f <file path>
At one point on the list of files, Java will throw a File Not Found exception because it gets an incorrect path. There is always only one character missing. And the preceding file entries are read correctly.
I tried to get the length of the string when one character got missing, and it is always on 8090th character.
Example:
If I have a list of files in a nested directory. My input will be something like this.
-f test\test1\test1_test2\test1_test2_test3\test3_test4.txt
Repeated inputs of this kind would result to:
-f test\test1\test1_test2\test1_test2_test3\test3_test4.txt
...
-f test\test1\test1_**tst2**\test1_test2_test3\test3_test4.txt
...
-f test\test1\test1_test2\test1_test2_test3\test3_test4.txt
There is a missing "e" which should be the 8090th character. But the next file entries are being read correctly. What am I missing?
Quoting MS Support
In Command Prompt, the total length of the following command line that you use at the command prompt cannot contain more than either 2047 or 8191 characters (as appropriate to your operating system)
So this means you cannot pass arguments to your program longer than 8191 characters. But workaround could be storing your arguments into the file and pass that file through command line to your program.
Make a second main class, where the main reads a file with the arguments.
public class MainWithArgsFile {
public static void main(String[] fileArgs) {
List<String> args = new ArrayList<>();
// Fill args:
for (String fileArg: fileArgs) { // One or more files.
try (BufferedReader in = new BufferedRead(new InputStreamReader(
new FileInputStream(new File(fileArg)), "UTF-8"))) {
for (;;) {
String line = in.readLine();
if (line == null) {
break;
}
//args.add(line); // One arg per line (for instance).
Collections.addAll(args, line.split(" +"));
}
}
}
OriginalMain.main(args.toArray(new String[args.size()]);
}
}