Last night I asked a question like this, I'm not sure what's happening and I have encountered another problem so here goes:
My instructor has given my class a project a program that reads a file, reads each letter and then prints out the amount of hits, outs, walks and sacrifice flies that each line has. I posted some more info in my original question about this topic.
I have rewritten the code in chance that I would better my chances of getting the program to work. I learned about what substrings are and a bit more about tokens and came together with this program:
import java.util.Scanner;
import java.io.*;
public class BaseballStats
{
public static void main(String[]args) throws IOException
{
Scanner fileScan, lineScan;
String fileName;
int oCount = 0, hCount = 0, sCount = 0, wCount = 0;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the name of the input file: ");
fileName = scan.nextLine();
fileScan = new Scanner(new File(fileName));
while (fileScan.hasNext())
{
lineScan = new Scanner (fileName);
lineScan.useDelimiter(",");
String input = lineScan.nextLine();
int point =(input.indexOf(","));
String name = input.substring(0,point);
String records = input.substring(point,input.length());
for (int i = 0; i < records.length(); i++)
{
if (records.charAt(i) == 's')
sCount++;
else if (records.charAt(i) == 'o')
oCount++;
else if (records.charAt(i) == 'h')
hCount++;
else if (records.charAt(i) == 'w')
wCount++;
}// end of for loop
System.out.printf("Name: %s. Hits: %d. Outs: %d. Walks: %d. Sacrifice flies: %d.", name, hCount, oCount, wCount, sCount);
System.out.println();
}//end of while loop
}//end of main
}// end
The program runs fine, but after I enter in stats.dat(The file that is supposed to be reading), I get the following exception error:
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)
at BaseballStats.main(BaseballStats.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
It points to line 25, which is the
String name = input.substring(0,point);
line. I have been stumped on this, am I missing something?
Note: I have read Adamski's suggestion on the original question. I tried to follow it but as I'm new to java I'm having a hard time understanding encapsulation, specifically the setter and getter methods. I figured it would be best to leave them alone for now until next chapter, where my class explains them.
What you're dealing with is called an "edge condition." It's a situation that isn't the most common situation for your algorithm. But you have to deal with the rare situations as well to avoid errors.
You've got the following code:
String input = lineScan.nextLine();
int point =(input.indexOf(","));
String name = input.substring(0,point);
This is a problem of bug diagnosis (which programmers do all day long.) You need to now ask yourself the following:
What does "StringIndexOutOfBoundsException" mean? Google will tell you that.
How could that possibly be? What would cause that error when calling substring? (Google java substring to see what causes substring could throw that exception.)
This will have you looking at the indexOf() method (again, google is your friend) and what kind of results would come back from that that could lead to that stack trace.
What kind of input could lead to THAT situation?
Hope that gets you moving forward again.
String#indexOf(String) returns -1 if the passed in parameter is not found in this String.
So, input is likely not finding a , in it:
int point =(input.indexOf(","));
And when you pass in a negative index into String.substring(int, int), an StringIndexOutOfBoundsException will be thrown.
String name = input.substring(0,point); // input.substring(0, -1); will throw the exception
Related
I made a method within a class that is supposed to parse a file with the format: name, xxx-xxx-xxxx
for every line. I'm trying to grab the phone number and put every digit into an array of ints and return that array. Here is my code.
This is the line that causes the error---
theIntNumber=Integer.parseInt(justAnotherString);
If I had: Nicholas James, 912-345-6789
then....
justAnotherString = "9123456789" and it throws an error when trying to parse that string for an int. I'm confused as to why this is happening, shouldn't it parse the int from this string?
Thank you for any answers.
public int[] getPhoneNumberArray() throws FileNotFoundException
{
Scanner scan = new Scanner(file);
while(scan.hasNextLine())
{
String thePhoneNumber = "";
String justAnotherString = "";
int theIntNumber=0;
String line = scan.nextLine();
Scanner parser = new Scanner(line);
parser.useDelimiter(",");
parser.next();
parser.useDelimiter(" ");
parser.next();
thePhoneNumber = parser.next();
Scanner lol = new Scanner(thePhoneNumber);
lol.useDelimiter("-");
justAnotherString += lol.next();
justAnotherString += lol.next();
justAnotherString += lol.next();
theIntNumber=Integer.parseInt(justAnotherString);
for(int i=10;i>0;i--)
{
phoneNumberArray[i-1]=theIntNumber%10;
}
}
for(int a=0;a<10;a++)
{
System.out.println("Phone Number: ");
}
return phoneNumberArray;
}
EDIT: Previous number was 123-456-7890. The number I had before was larger than the 2.1 billion that java can handle. 987-654-3210 is a better example.
This is the error I'm getting.
Exception in thread "main" java.lang.NumberFormatException: For input string: "9876543210"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at exam2.Contact.getPhoneNumberArray(Contact.java:71)
at exam2.ExamTwoInput.main(ExamTwoInput.java:83)
Your code is working here, the only issue I see is that your formula for converting the digits of the int number to an array appears flawed. You don't need the int anyway, since you have it as justAnotherString. Basically, you could use Character.digit(char, int) like -
int[] phoneNumberArray = new int[justAnotherString.length()];
for (int i = 0; i < justAnotherString.length(); i++) {
phoneNumberArray[i] = Character.digit(justAnotherString.charAt(i), 10);
}
System.out.println(Arrays.toString(phoneNumberArray));
Of course, you could also parse the telephone number with something like
String line = "Nicholas James, 123-456-7890";
// get everything after the last space.
String phone = line.substring(line.lastIndexOf(' ') + 1);
phone = phone.replace("-", ""); // remove the '-' symbols
int[] phoneNumberArray = new int[phone.length()];
for (int i = 0; i < phone.length(); i++) {
phoneNumberArray[i] = Character.digit(phone.charAt(i), 10);
}
System.out.println(Arrays.toString(phoneNumberArray));
which has the advantage that it will work with (and without) dashes.
As an aside, you can't store a telephone number in an integer. It loses both leading zeroes, and the plus sign.
For instance, imagine you were given the number for the British Prime Minister, +44 20 7925 0918. The plus sign there indicates that the call is an international call. It would be replaced by 011 in the North American Numbering Plan, or by 00 in the European Telephony Numbering Space. How would you represent that telephone number as an int?
I know this question is so old, but till now not have accepted answer.
as your note:
EDIT: Previous number was 123-456-7890. The number I had before was larger than the 2.1 billion that java can handle. 987-654-3210 is a better example.
so, please use Long.valueOf(str) instead of Integer.parseInt(str) or Integer.valueOf(str)
hope this help u all :)
I am making a decryption program and I'm not quite sure how to use the variable "cip" out side of my try catch block. I tried moving the 3 lines of where is asks user to input pattern but i ran into other problems.
my code is:
import java.util.*;
public class unscrambler //This class will encrpyt the program
{
public static void main (String [] args){
int cip= 0;
String user ="";
System.out.println("Please enter the code to unscramble");
Scanner inputScanner = new Scanner(System.in); //imports scanner reader
String userinput = inputScanner.next();
char[] charArray = userinput.toCharArray(); //sends userinput to charArray
int j=charArray.length;
Character [] array = new Character[j];
for(int w=0; w<j; w++){
array[w] = charArray[w];
}
int a=1;
System.out.println("Please enter the number cipher pattern (an integer)");
do{
try{
user = inputScanner.next();
cip = Integer.parseInt(user);
a=2;
System.out.println("your code is ");
for(int w =0; w<j;){
System.out.println(charArray[j]);
w+=cip;
}
if(cip<=0){
System.out.println("please enter number greater than zero");
a=1;
}
}catch(NumberFormatException f){
System.out.println("please enter a proper number");
}
}while(a==1);
}
}
You're only making the declarations in that block.
String user = inputScanner.next();
int cip = Integer.parseInt(user);
Add these to the start of the file, just after the main() line:
int cip = 0;
String user = "";
The errors after just moving (without the = stuff) indicate that you're using cip after the try block, so we need to initialise it with empty data in case the try fails.
Now just change the lines that you've currently got in the try block to:
// Remove the 'String' part.
user = inputScanner.next();
// Remove the 'int' part.
cip = Integer.parseInt(user);
And then you can move on to the next unrelated bug.
The solution is to either move the variable declaration outside of the loop, or move the place you want to use it inside the loop.
Java doesn't allow you to use a local variable outside of the scope in which it was declared. Period.
I tried moving the 3 lines of where is asks user to input pattern but i ran into other problems.
Well ... you need to solve those other problems!
Programming is like this. You need to work within the constraints of the programming language that you are using.
I can see what is causing your latest error, but I'm not going to tell you what it is. Instead, I'm going to tell you how to find it for yourself.
The "line upon line of output" is a Java Stacktrace. It contains A LOT of useful information, and you need to learn how to interpret it.
java.lang.ArrayIndexOutOfBoundsException: 5
at unscrambler.main(unscrambler.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
Stacktraces typically report an exception that has been thrown somewhere in your running program.
Step 0: Find the stacktrace.
The first line gives the name of the exception, and the message. In this case, the name of the exception is ArrayIndexOutOfBounds and the message is (just) "5".
Step 1: If you don't recognize the name of the exception, look it up in the javadocs.
Here it is: link. Read it now.
Step 2: Try to understand the message. In this case, you just need to know that the message is the value of the index that was out of range. But you should be able to guess that ... based on the javadoc for the exception. (Usually the messages are a bit more informative, but this one is being thrown from compiled code, and for technical reasons a more informative error would be difficult to produce.)
The second line of the stacktrace tells you where the exception was thrown. In this case, line 35 of "unscrambler.java" ... in the main method.
Step 3: Open the source file in an editor or your IDE, and see what the code at that line says.
In this case it is (I think) this line:
System.out.println(charArray[j]);
Step 4: Now you have to start thinking. (Thinking is a very important part debugging!) How can that line have possibly thrown that exception? What could have caused that?
In this case, the first think to observe is that there is only one place on that line where you are doing array indexing, and it is the expression charArray[j]. So that means that ... (you fill in the details). But were did ... (you fill in the details) come from? Take a look at what happened before this statement. See it yet? (If no, then look again. It should be really obvious if you look carefully!)
The rest is for you to sort out ... :-)
For an assignment I have due, my group and I were asked to code an educational/interactive game, and we decided on a basic maths one.
To get the users answers, we decided to use Java Scanner and put this line of code at the top of all the code we have;
java.util.Scanner
One of the loops that use this is the page with the questions on it, the loop looking something like this;
scoreCount = 0;
for (questions = 0; questions < 5;) {
//get the user's answer
userAnswer[questions] = input.nextInt();
//text box for users answer
if (userAnswer[questions] == compAnswer) {
//put tick next to answer
//add one to score
scoreCount = scoreCount + 1;
} else if (userAnswer[questions] != compAnswer) {
//put cross next to answer
}
//go to next question
questions++ ;
}
I'm working through all the errors that were thrown up and every time i don't have java.util.Scanner commented out Processing throws us the errors unexpected token: and then either class or void, which i don't get, but when java.util.Scanner is commented out, the classes and voids all work and the .input.nextInt() isn't recognised.
I am new to Java programming and Processing, any help at all would be greatly appreciated
EDIT
i think this is the link which lets you see my code, it's called Test;
https://github.com/MeganSime/Week8DataVis
you have to check if scanner has next int (token)
Scanner input = new Scanner(System.in);
.
.
if(input.hasNextInt()) { // or hasNext()
userAnswer[questions] = input.nextInt();
}
You're probably inserting a non int value where the scanner expects that. You should do something like that:
if(input.hasNextInt()) {
userAnswer[questions] = input.nextInt();
} else {
scan.next(); //consume any non-int value like ":"
}
In my program, it reads a file called datafile.txt... inside the datafile.txt is a random 3 lines of words. What my program does is reads the file the user types in and then they can type in a Line # and Word # and it will tell them the word that is in that location.. for example..
What is the file to read from?
datafile.txt
Please enter the line number and word number (the first line is 1).
2 2
The word is: the
My problem is that my program reads the 3 lines in the txt doc as 0, 1 ,2 and the words start from 0. So to read the first word in the first line they would have to type 0,0 instead of 1,1. What I am trying to do is make it work so they can type 1,1 instead of 0,0. Not sure what my problem is right now, here is my code....
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class readingFile {
/**
* #param args
* #throws IOException
* #throws validException
*/
public static void main(String[] args) throws IOException, checkException
{
System.out.println("Enter file name: " );
Scanner keyboard = new Scanner(System.in);
BufferedReader inputStream = null;
ArrayList<String> file = new ArrayList<String>();
String fileName = keyboard.next();
System.out.println ("The file " + fileName +
" has the following lines below: ");
System.out.println();
try
{
inputStream = new BufferedReader(new FileReader(fileName));
ArrayList<String> lines = new ArrayList<String>();
while(true)
{
String line = inputStream.readLine();
if(line ==null)
{
break;
}
Scanner itemnize = new Scanner(line);
while(itemnize.hasNext())
{
lines.add(itemnize.next());
}
lines.addAll(lines);
System.out.println(lines+"\n");
}
System.out.println("Please enter the line number and word number");
int index1 = keyboard.nextInt();
int index = keyboard.nextInt();
System.out.println("The word is: "+ lines.get(index));
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file " + fileName);
}
inputStream.close();
}
private static void checkValid(ArrayList<String> items, int index) throws checkException
{
throw new checkException("Not Found");
}
}
The obvious solution to adapt 1-based user input to 0-based internal representation is to subtract one at some point. Seeing that you don't even use index1, writing
lines.get(index - 1)
isn't going to solve your problem completely. But I guess you can take it from there, and do something similar for the word index.
As I assume you are just learning to program I will point out 3 areas of improvement
Much like how mathematics has BIDMAS which determines the order of evaluation of an expression Java and other program languages evaluate statements in a particulate way. This means within the Parentheses of a function you may include a statment instead of a variable or constant. This will be evaluated with the result (or return) been passed into the called function. This is why MvG says you can do lines.get(index - 1)
Not all exceptions you should consider and plan around will the compiler inform you about. For example in your code an invalid input for line number or word number is entered you will get a Runtime Exception (array index out of bound)
Naming of variables should be useful, you have index and index1. What's the difference? I assume from reading your code one should be the user selected index of the line number and the second should be the index of the word on said line. May I suggest requestedLineIndex and requestedWordIndex.
On a final note this is not a usual StackOverflow question hence why your question has been 'voted down'. If you are learning as part of a course is there a course forum or Virtual Learning Environment (VLE) you can post questions on? The support of your peers at the same level of learning tends to help with exploring the basics of a language.
This is driving me insane! Here's the code:
public static void main(String[] strings) {
int input;
String source;
TextIO.putln("Please enter the shift value (between -25..-1 and 1..25)");
input=TextIO.getInt();
while ((input < 1 || input > 25) && (input <-25 || input >-1) && (input != 999 && input !=-999))
{
TextIO.putln(input + " is not a valid shift value.");
TextIO.putln("Please enter the shift value (between -25..-1 and 1..25)");
input=TextIO.getInt();
}
TextIO.putln("Please enter the source text (empty line to quit)");
//TextIO.putln(source);
source = TextIO.getln();
TextIO.putln("Source :" + source);?");
}
}
However, its telling me that 'source' is never read! It's not allowing me to get input! Can anyone see what the problem may be?
The compiler is correct; the variable source is never read. You're assigning a value to it (source = TextIO.getln();), but you're never reading that value back out.
To do so, you could do something like:
TextIO.putln(source);
You seem to be having trouble reading text from the console with the TextIO class. Here's a more standard approach, introduced in Java 5:
String source;
Scanner in = new Scanner(System.in);
source = in.nextLine();
What exactly do you wish to do with the variable source? As it stands, you're asking the user to enter a string, but you're not doing anything with that string.
You should probably ask one of your friends for help instead of posting our homework online. I feel as though this is subjective to cheating. If you are having trouble already, it is only going to get worse. You should be breezing through your freshman year.