ArrayIndexOutOfBounds When Splitting String - java

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.

Related

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.

Read a csv-file value by value with Scanner, useDelimiter(";") not working

I am trying to read a CSV file value by value using Scanner.useDelimiter(";").
However Scanner.nextLine() still returns the whole line instead of a single Value.
The CSV-file looks like this:
0.00034;0.1;0.3;0.6;1,00E-13
My code:
Scanner iStream = new Scanner(new InputStreamReader(new FileInputStream(file.cvs);
iStream.useDelimiter(";");
String[] test = new String[5];
for (int i = 0; i < 5; i++) {
test[i] = iStream.nextLine();
}
Result:
"0.00034;0.1;0.3;0.6;1,00E-13"
Expected Result:
"0.00034", "0.1", "0.3", "0.6", "1,00E-13"
Is this possible, or should I use String.split()?
Am I missing something?
Apart from the fact that this problem is ready-made for a parsing library such as OpenCSV, nextLine doesnt account for delimiter patterns. Use next instead
test[i] = iStream.next();
From the Java Scanner documentation:
public String next()
Finds and returns the next complete token from this scanner.
A complete token is preceded and followed by input that matches the delimiter pattern.
This literally answers your question. However, I am not sure about next's behaviour at the start and end becuase it has to be "preceded and followed" by the delimiter. Maybe someone can fill in on this?
You could add extra characters to your delimiter, like \netc.

Using String.split on input file

So I have an input file of the form:
AdjGraphHeader
11
20
30
.
.
.
and I need to create a string array that holds each line separately. So I read the file using:
String s = FileUtils.readFileToString(f);
Words w = new Words(s, (long)s.length());
and then the words constructor did the following:
public Words(String str, long n_) {
strings = str.split("\\n");
string = str;
n = n_;
m = strings.length;
}
The issue seems to be that there is an extra line at the end of adjGraphHeader, but I have no idea how to get rid of it. Any help would be greatly appreciated.
I suspect that your lines are separated not by \n but by \r\n so if you remove \n you still have \r after each word and while printing it you will see empty line. One of solutions could be splitting using this regular expression
"\r?\n|\r" - ? makes element described before it optional, | represent "or" operator
which will handle line separators if forms \r \r\n \n.
You can also use something IMHO simpler like
List<String> lines = Files.readAllLines(Paths.get("locationOfFile"));
or if you already have File f
List<String> lines = Files.readAllLines(f.toPath());
and store each line in list (you can later convert this list to array if you really need it)

How to delete duplicated characters in a string?

Okay, I'm a huge newbie in the world of java and I can't seem to get this program right. I am suppose to delete the duplicated characters in a 2 worded string and printing the non duplicated characters.
for example:I input the words "computer program." the output should be "cute" because these are the only char's that are not repeated.
I made it until here:
public static void main(String[] args) {
System.out.print("Input two words: ");
String str1 = Keyboard.readString();
String words[] = str1.split(" ");
String str2 = words[0] + " ";
String str3 = words[words.length - 1] ;
}
but i don't know how to output the characters. Could someone help me?
I don't know if I should use if, switch, for, do, or do-while...... I'm confused.
what you need is to build up logic for your problem. First break the problem statement and start finding solution for that. Here you go for steps,
Read every character from a string.
Add it to a collection, but before adding that, just check whether it exists.
If it exists just remove it and continue the reading of characteer.
Once you are done with reading the characters, just print the contents of collection to console using System.out.println.
I will recommend you to refer books like "Think like A Programmer". This will help you to get started with logic building.
Just a hint: use a hash map (http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html).
Adding following code after last line of your main program will resolve your issue.
char[] strChars = str2.toCharArray();
String newStr="";
for (char c : strChars) {
String charStr = ""+c;
if(!str3.contains(charStr.toLowerCase()) && !str3.contains(charStr.toUpperCase())){
newStr+=c;
}
}
System.out.println(newStr);
This code loops through all the characters of the first word and check if the second string contains that character (In any form of case Lower or Upper). If it is not containing, adding it to output string and at the end printing it.
Hope this will work in your case.
How about doing it in just 1 line?
str = str.replaceAll("(.)(?=.*\\1)", "");

NumberFormatException given an input String holding a small integer

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.

Categories

Resources