NumberFormatException given an input String holding a small integer - java

I have a String from which I would like to parse an integer and cannot find a way past this runtime exception. I understand that it is meant to display at times when a parseNUMBERTYPE function is applied to an inappropriately defined String, and that blank spaces or letters where the code expects numbers to be can trigger it. However, the String I am using as a test dummy is as far as I can tell simply the numeral 5. I have seen several suggestions in response to other users' NumberFormatException problems advocating the application of a trim() function before parsing, and I have tried this with no success.
I have also tried replacing the String I wish to parse with the simple, unstored value "5". This is the same as what the program seems to report as the relevant variable's stored String value, but while parsing that variable fails with this post's eponymous exception, the unstored value appears to run perfectly well in its place.
Note that the String variable is read by a File Scanner. I must suppose my problem has something to do with unknown, unwanted, 'invisible' characters that are being read in addition to the number five, but I cannot determine why this is happening or how to stop it. The file is formatted as .txt
Here is my code:
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the file name:");
String filename = scan.nextLine();
File tempfile = new File(filename);
Scanner filereader = new Scanner(tempfile);
//this is meant to assign to the String line1 the numerical value (5)
//of the file's first line
String line1 = filereader.nextLine();
//this was added later to determine if line1 held the value I expect
//it outputs the single digit 5, as expected and appropriate
System.out.println(line1);
//this was added to test how flawed my system was
//it runs fine, indicating to me that the problem may in my reader
int num2 = Integer.parseInt("5");
//this is where the exception is cast
int num1 = Integer.parseInt(line1);
I am presented with these errors:
Exception in thread "main" java.lang.NumberFormatException: For input string: "5"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at Driver.main(Driver.java:26)
Your assistance is appreciated.
In response to the suggestions given so far, the code has been modified to appear as follows:
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the file name:");
String filename=scan.nextLine();
File tempfile = new File(filename);
Scanner filereader = new Scanner(tempfile);
//this is meant to assign the String line1 the numerical value (5)
//of the file's first line
String line1 = filereader.nextLine();
//this was added after to determine if line1 held the value I expect
//it outputs the single digit 5, as expected and appropriate
System.out.println("["+line1+"]");
//this was added to test how flawed my system was
//it runs fine, indicating to me that the problem is in my reader
int num2 = Integer.parseInt("5");
//this is where the exception is cast
int num1 = Integer.parseInt(line1.trim());
Please correct me if I have misinterpreted your guidance in some way. As it stands, the problem persists, with an identical error report.

Looking at the message in the exception, it shows that there are no additional visible characters or whitespace in the string since the 5 is surrounded by quotes (and a quick check of the Java source code shows that the message printed here does not appear to be modified to remove whitespace before surrounding the string with quotes).
This means that either there are hidden non-printing characters in your string, or the 5 itself is actually not a 5 at all, and is instead some unicode character from another language that resembles a 5.
Simple debug case to sort this out would be to print the length of your string, as this will quickly sort out whether there are additional hidden characters in it.
System.out.println("String: [" + line1 + "] size: " + line1.size());
After that, a regex can be used to get the first consecutive set of digits, if that is the desired behaviour:
Pattern pattern = Pattern.compile("(\\d+)");
Matcher matcher = pattern.matcher(line1);
if (matcher.find())
{
String digits = matcher.group();
int num = Integer.parseInt(digits);
}
Alternatively, if it is possible or desired to remove characters in between digits then a replaceAll can be used:
String digits = line1.replaceAll("[^0-9]","");
For the string "5 6", the first method will give you 5, and the second will give you 56.

Related

Using scanner.next() to return the next n number of characters

I'm trying to use a scanner to parse out some text but i keep getting an InputMismatchException. I'm using the scanner.next(Pattern pattern) method and i want to return the next n amount of characters (including whitespace).
For example when trying to parse out
"21 SPAN 1101"
I want to store the first 4 characters ("21 ") in a variable, then the next 6 characters (" ") in another variable, then the next 5 ("SPAN "), and finally the last 4 ("1101")
What I have so far is:
String input = "21 SPAN 1101";
Scanner parser = new Scanner(input);
avl = parser.next(".{4}");
cnt = parser.next(".{6}");
abbr = parser.next(".{5}");
num = parser.next(".{4}");
But this keeps throwing an InputMismatchException even though according to the java 8 documentation for the scanner.next(Pattern pattern) it doesn't throw that type of exception. Even if I explicitly declare the pattern and then pass that pattern into the method i get the same exception being thrown.
Am I approaching this problem with the wrong class/method altogether? As far as i can tell my syntax is correct but i still cant figure out why im getting this exception.
At documentation of next(String pattern) we can find that it (emphasis mine)
Returns the next token if it matches the pattern constructed from the specified string.
But Scanner is using as default delimiter one or more whitespaces so it doesn't consider spaces as part of token. So first token it returns is "21", not "21 " so condition "...if it matches the pattern constructed from the specified string" is not fulfilled for .{4} because of its length.
Simplest solution would be reading entire line with nextLine() and splitting it into separate parts via regex like (.{4})(.{6})(.{5})(.{4}) or series of substring methods.
You might want to consider creating a convenience method to cut your input String into variable number of pieces of variable length, as approach with Scanner.next() seems to fail due to not considering spaces as part of tokens (spaces are used as delimiter by default). That way you can store result pieces of input String in an array and assign specific elements of an array to other variables (I made some additional explanations in comments to proper lines):
public static void main(String[] args) throws IOException {
String input = "21 SPAN 1101";
String[] result = cutIntoPieces(input, 4, 6, 5, 4);
// You can assign elements of result to variables the following way:
String avl = result[0]; // "21 "
String cnt = result[1]; // " "
String abbr = result[2]; // "SPAN "
String num = result[3]; // "1101"
// Here is an example how you can print whole array to console:
System.out.println(Arrays.toString(result));
}
public static String[] cutIntoPieces(String input, int... howLongPiece) {
String[] pieces = new String[howLongPiece.length]; // Here you store pieces of input String
int startingIndex = 0;
for (int i = 0; i < howLongPiece.length; i++) { // for each "length" passed as an argument...
pieces[i] = input.substring(startingIndex, startingIndex + howLongPiece[i]); // store at the i-th index of pieces array a substring starting at startingIndex and ending "howLongPiece indexes later"
startingIndex += howLongPiece[i]; // update value of startingIndex for next iterations
}
return pieces; // return array containing all pieces
}
Output that you get:
[21 , , SPAN , 1101]

How to extract words from a string in Java

I've imported a file and turned it into a String called readFile. The file contains two lines:
qwertyuiop00%
qwertyuiop
I have already extracted the "00" from the string using:
String number = readFile.substring(11, 13);
I now want to extract the "ert" and the "uio" in "qwertyuiop"
When I try to use the same method as the first, like so:
String e = readFile.substring(16, 19);
String u = readFile.substring(20, 23);
and try to use:
System.out.println(e + "and" + u);
It says string index out of range.
How do I go about this?
Is it because the next two words I want to extract from the string are on the second line?
If so, how do I extract only the second line?
I want to keep it basic, thanks.
UPDATE:
it turns out only the first line of the file is being read, does anyone know how to make it so it reads both lines?
If you count the total number of characters for each string, they are more than the indexes your entering.
qwertyuiop00% is 13 characters. Call .length() method on the string to verify the length is the one you expect.
I would debug with adding the following before:
System.out.println(readFile);
System.out.println(readFile.length());
Note:
qwertyuiop00% qwertyuiop is 24 characters since space counts as a character. Unless ofcourse you don't have the space in which it's 23 characters and your indexes are 0 to 22
Note2:
I asked for the parser code since I suspect your using the usual code which is something like:
while ((line = reader.readLine()) != null)
You need to concatenate those lines into one String (though it's not the best approach).
see: How do I create a Java string from the contents of a file?
First split your string into lines, you could do this using
String[] lines = readFile.split("[\r\n]+");
You may want to read the content directly into a List<String> using Files.#readAllLines instead.
second, do not use hard coded indexes, use String#indexOf to find them out. If a substring does not occur in your original string, then the method retunrs -1, always check for that value and call substring only when the return value is not -1 (0 or greater).
if(lines.length > 1) {
int startIndex = lines[1].indexOf("ert");
if(startIndex != -1) {
// do what you want
}
}
Btw, there is no point in extracting already known substring from a string
System.out.println(e + "and" + u);
is equivalent to
System.out.println("ertanduio");
Knowing the start and end position of a fixed substring makes only sence if you want to do something with rest of original string, for example removing the substrings.
You may give this a try:-
Scanner sc=new Scanner(new FileReader(new File(The file path for readFile.txt)));
String st="";
while(sc.hasNext()){
st=sc.next();
}
System.out.println(st.substring(2,5)+" "+"and"+" "+st.substring(6,9));
Check out if it works.

for loop in Java runs 3 times before taking next input

I am new to Java and learning it. I was trying out a code to actually see how the for-each loop works in Java. But I faced a problem regarding that. My code is simple :
class ForEach
{
public static void main(String[] args) throws java.io.IOException
{
char[] array = new char[10];
for(int i = 0; i < 10; i++)
{
System.out.println("Enter Character " + i);
array[i] = (char)System.in.read();
}
System.out.println("Displaying characters in array : ");
for(char i : array)
{
System.out.println(i);
}
}
}
but the output is awkward. I am sure something is wrong with my code. I can't just find it.
The output of this code is :
Enter Character 0
a
Enter Character 1
Enter Character 2
Enter Character 3
b
Enter Character 4
Enter Character 5
Enter Character 6
c
Enter Character 7
Enter Character 8
Enter Character 9
d
Displaying characters in array :
a
b
c
d
I do not understand why is the for loop running thrice before it takes another input from user?
Any help? Thank you in advance.
I'm assuming you're on Windows, because this behavior seems about right for Windows.
When you enter a character, you do something like this:
Press a
Press return
Step 2 passes a line separator sequence that indicates to the input console that you have pressed enter, which tells the console that you have finished entering this line of input. So the console passes the entire line to your program.
This line separator sequence on Windows is made up of the carriage return character '\r' followed by the newline character '\n'. So your line is really "a\r\n".
What System.in.read() does is read a single byte from the input console. As the characters you input all fit into a single byte, what your program does is consumes the inputted characters one by one, so it's something like this:
Output: Enter Character 0
> User inputs: "a\r\n" // You only entered 'a', the other two characters are from the enter key
array[0] = System.in.next(); // sets array[0] to 'a', "\r\n" are still "waiting" on the input stream
Output: Enter Character 1
> String "\r\n" is still on input, so read from those:
array[1] = System.in.next(); // sets array[1] to '\r', "\n" is still "waiting"
Output: Enter Character 2
> String "\n" is still on input, so read from that
array[2] = System.in.next(); // sets array[2] to '\n', input source is now empty
Output: Enter Character 3
> Nothing is waiting on the input stream, so program waits for user input
... and so on
What you want to do is make a Scanner, and read an entire line at once, so the only character you process is the content you entered:
Scanner scanner = new Scanner(System.in); // Creates a new scanner that reads from System.in
String line = scanner.nextLine(); // Reads an entire line from console, **not including newline breaks at the end of a line**
// use line.charAt(i) to get individual characters, or use line.toCharArray() to get the string's backing char[]
If you were to print the integer values of each of the elements in your array, you'd actually see numbers where your console outputs blank lines. These numbers are the ASCII numerical equivalents to the '\r' and '\n' characters.
Interestingly, I believe that if you were run this on a *nix system you'd only skip a single line instead of two. This is because *nix systems use just '\n' as their line separator, so you'd only have a single extra character at the end of your line.
Also, I'm not entirely sure why your console is outputting a line for both '\r' and '\n'; could be that Java breaks lines for both characters internally, while Windows does not. So you might even get different results if you were to try to run this in a Windows shell.
From the Java API:
Reads the next byte of data from the input stream.
What happens is when you type a followed by a newline, there are actually three bytes to read (I'm guessing a followed by carriage return and newline). Hence, the input you provide is enough to keep read() running for three iterations.
I recommend you to use Scanner for input reading instead.

scanner is not storing strings past a "space"

Firstly, I'm very beginner, but I like to think I mildly understand things.
I'm trying to write a method that will store the user's input into a string. It works just fine, except if the user puts in a space. Then the string stops storing.
public static String READSTRING() {
Scanner phrase = new Scanner(System.in);
String text = phrase.next();
return text;
}
I think the problem is that phrase.next() stops scanning once it detects a space, but I would like to store that space in the string and continue storing the phrase. Does this require some sort of loop to keep storing it?
Use .nextLine() instead of .next().
.nextLine() will take your input until a newline character has been found (when you press enter, a newline character is added). This essentially allows you to get one line of input.
From the Javadoc, this is what we have:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
Either you can use phrase.nextLine() as suggested by others, or you can use Scanner#useDelimiter("\\n").
Try phrase.nextLine();. If I recall correctly, Scanner automatically uses spaces as delimiters.
Try
pharse.NextLine();
and you got do an array for limited words
String Stringname = {"word","word2"};
Random f = new Random(6);
Stringname = f.nextInt();
and you can convert an integer to string
int intvalue = 6697;
String Stringname = integer.ToString(intvalue);

ArrayIndexOutOfBounds When Splitting String

I am trying to extract information from a file that is formatted as follows:
1
test#mail.ca|password|false
However, I seem to be getting ArrayIndexOutOfBounds errors when running the following code and I am unable to determine the reason for this as I believe that my splitting should be functioning correctly. The error is obtained on the line beginning with "users".
sc = new Scanner (System.in);
BufferedReader in = new BufferedReader (new FileReader (USAVE));
int repeats = Integer.parseInt(in.readLine());
for (int c = 0; c < repeats; c++){
String info = in.readLine();
System.out.println (info);
String[] extracted = info.split("\\|");
users.addUser(extracted[0], decryptPassword(extracted[1]));
}
in.close();
What could be the problem?
EDIT: I have changed "|" to "\|" but the problem persists.
EDIT2: StackTrace
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at OnlineCommunications.userFromFile(OnlineCommunications.java:165)
at OnlineCommunications.logIn(OnlineCommunications.java:36)
at OnlineCommunications.emailOption(OnlineCommunications.java:593)
at OnlineCommunications.main(OnlineCommunications.java:683)
The method I have posted above is the one named userFromFile.
String#split(regex) expects regex as a parameter and | is a meta character(special character) in regex world. In order to treat a meta charcter as a normal character you should escape it with backslash(\|)
String[] extracted = info.split("\\|");
or just include it inside a charcter class
String[] extracted = info.split("[|]");
Below are the meta characters in regex:
<([{\^-=$!|]})?*+.>
String.split(String regex) takes a regular expression as an argument, use:
String[] extracted = info.split("\\|");
similar post. Tokenizing Error: java.util.regex.PatternSyntaxException, dangling metacharacter '*' You have to use like this :
String[] extracted = info.split("\\|");
Actually there is nothing wrong with how you are parsing the string. The error lies elsewhere. I would add System.out.println (repeats) just before you enter the loop to make sure you are iterating the correct number of times. To debug even further, I would print the contents of extracted (Arrays.toString(extracted)) before the line invoking user.addUsers. If all that looks good, then the problem lies in the user.addUsers invocation.

Categories

Resources