Java String index out of bounds with text file input - java

I am trying to split a String input into two using the following code:
public TypeValue(String line) {
while (line.charAt(i) != ' ') {
i++;
System.out.println(i);
}
type = line.substring(0,i);
value = line.substring(i);
}
my input is a textfile that looks like this:
10 16
10 32
10 9024720
F 10
F 1
F 111111
F 100000
F 10110110100111001
However, I always get a java.lang.StringIndexOutOfBoundsException: String index out of range: 13. This only happens when I try to read the input from a text file. When I use the terminal to input the lines one by one it works just fine.
I have been looking for a couple hours but I cannot figure out what is causing this. It is also always "13", even when I delete all but the first line from the text file. Can anybody help me with this?
Edit: Thank you for the help everybody. The problem was with something else entirely. I didn't properly put my File in the Scanner in my main method...

You should simply use line.split(" ") which will return an array of String, then get either the first or the second value using respectively the index 0 and 1 of the resulting array as next:
String[] values = line.split(" ");
type = values[0];
value = values[1];
Another way could be to use line.indexOf(' ') to get the index of the space character in your String.
int index = line.indexOf(' ');
// From 0 to the index where we found the space
type = line.substring(0, index);
// Starts from index + 1 to skip the space
value = line.substring(index + 1);

You forgot to initialize i. Try this:
public TypeValue(String line) {
int i=0;
while (line.charAt(i) != ' ') {
i++;
System.out.println(i);
}
type = line.substring(0,i);
value = line.substring(i);
}

Try comparing raw ascii values than characters,
as in
public TypeValue(String line) {
int i=0;
//ascii value for space is 32
while ((int)line.charAt(i) != 32) {
i++;
System.out.println(i);
}
type = line.substring(0,i);
value = line.substring(i);
}

Related

How do I merge the indexes in an array to create 1 main array/String in Java?

The input is supposed to be
ABDECDEABCAADD
ABCDE
The first line is a random piece of text. The second line is a circular shift.
The output is supposed to be:
yes
This program is supposed to take a piece of text and determine if it contains a circular shift based on the second line of input.
A circular shift is when you take the first letter of the string and move it to the back of the string. Thus creating a new string.
If the text entered contains a circular shift from the second line then the output would be yes otherwise it would be no.
Since ABDECDEABCAADD contains DEABC which is a shift of ABCDE the output would be yes.
Scanner scan = new Scanner(System.in);
String text;
System.out.println("Enter text:");
text=scan.nextLine();
System.out.println("Enter shift:");
String shift=scan.nextLine();
String[] split1=shift.split("");
String[] array2=new String[split1.length];
String[] array3=new String[split1.length];
for(int z=0;z<split1.length;z++) {
array2[split1.length-1]=split1[0];
for(int x=0;x<split1.length-1;x++) {
array2[x]=split1[x+1];
array3[0]=array2[x]+array2[x+1];
}
//if(text!=)
}
for(int y=0;y<array2.length;y++) {
System.out.print(array2[y]);
}
How I wanted to tackle this question was to first get the input then separate the second line into characters so I can create a circular shift. Once I'm done with that I would take the new order of characters and merge them to create a string.
I need help when it comes to the merging but also with how I can create multiple shifts.
If you see this pleas help.
Don't create shifts. For best performance, do it like this:
String text = "ABDECDEABCAADD";
String shift = "ABCDE";
Scan text for the first character in shift, i.e. scan for 'A'.
When found, match as many of the following characters as possible.
If not all characters in shift were matched, get the count of missing characters.
Grab that many characters from before the found 'A', if available.
If found and they match the remaining characters in shift, your search is done.
Repeat from step 1, searching for the next 'A'.
Example
static int matchShift(String text, String shift) {
if (shift.isEmpty())
throw new IllegalArgumentException("Shift value is empty");
char first = shift.charAt(0);
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == first) {
int j = 1;
while (j < shift.length() && i + j < text.length()
&& text.charAt(i + j) == shift.charAt(j))
j++;
if (j == shift.length())
return i; // Match found at index 'i', with unshifted value
int start = i + j - shift.length();
if (start >= 0 && text.substring(start, i).equals(shift.substring(j, shift.length())))
return start; // Match found at index 'start', with shifted value
}
}
return -1; // No match found
}
Test
public static void main(String[] args) {
test("ABDECDEABCAADD", "ABCDE");
}
static void test(String text, String shift) {
int i = matchShift(text, shift);
if (i == -1)
System.out.printf("'%s', '%s': No Match%n", text, shift);
else
System.out.printf("'%s', '%s': Match at index %d ('%s')%n",
text, shift, i, text.substring(i, i + shift.length()));
}
Output
'ABDECDEABCAADD', 'ABCDE': Match at index 5 ('DEABC')
It could also have responded with Match at index 4 ('CDEAB'). If that is important, change the logic to search for the last character instead of the first, match backwards, then compare substrings after.

How to fix this Run time error?

I am trying to make a java program which will find and remove repetative characters in string. Like if user types "baloon", the output should be "balon". I used String variable for input and copied its content to Char array so that I can analyze each character. I get ArrayIndexOutOfBoundsException. Here is my code
class doubleKiller{
private String inputStr = " ";
private char[] catchStr = new char[inputStr.length()];
private String modifiedStr;
//Accessor method
public void getString(String inputStr)
{
this.inputStr = inputStr;
}
public String killRepeater()
{
//copying string data to char array
this.inputStr.getChars(0 , this.inputStr.length() , catchStr , 0);
//------------------
for(int counter = 0 ; counter < this.inputStr.length() ; counter++)
{
if(catchStr[counter] != catchStr[counter - 1])
{
modifiedStr = modifiedStr + catchStr[counter];
}
}
return modifiedStr;
}
}
Here is Output when killRepeater() is called.
java.lang.ArrayIndexOutOfBoundsException: src.length=5 srcPos=0 dst.length=1 dstPos=0 length=4
at java.lang.System.arraycopy(Native Method)
at java.lang.String.getChars(String.java:894)
at doubleKiller.killRepeater(Main.java:23)
at useThings.main(Main.java:49)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.aide.ui.build.java.RunJavaActivity$1.run(SourceFile:108)
at java.lang.Thread.run(Thread.java:862)
Tell me my error...Thanks in advance
You are doing
private String inputStr = " ";
private char[] catchStr = new char[inputStr.length()];
inputStr.length() returns 1, that is, the size from the string " ", so, you have a char array with size 1.
When you do:
for(int counter = 0 ; counter < this.inputStr.length() ; counter++){
if(catchStr[counter] != catchStr[counter - 1]){
With a inputStr.length() > 1 you have an ArrayIndexOutOfBoundsException.
Also, when run catchStr[counter - 1]) for the first time, counter-1 would generate -1, which isn't a valid index. Try running the counter from 1 to avoid this error.
Declare your array with a fixed size(e.g 200) or use an ArrayList. You could also put catchStr = new char[inputStr.length()] after taking the input of the String.
Good thing that you asking about specific problem, but in case you interested how to make this simpler, there is regex magic
String in = "ballooooon";
String out = in.replaceAll("(.)\\1+", "$1"); // balon
Which means
find any symbol, save it to group 1, if next symbol, or symbols are equal to group 1, delete them and leave just one from the group.
You are initializing catchStr with inputStr.length(). But at this time inputStr = " ". So catchStr has a length of 1. When you later populate inputStr to a bigger value, you try and copy that into a char[] of length 1 and it doesn't fit. Add catchStr = new char[inputStr.length()]; right before you do the copy.
When you initialise catchStr it will always have the value of 1, because inputStr is " " and therefore it's length is 1.
private String inputStr = " ";
private char[] catchStr = new char[inputStr.length()];
When you loop on counter in the method killRepeater() you will get an ArrayOutOfBoundsException because the string you pass in getString is probably greater than 1.
Consider moving new char[inputStr.length()] into getString.
public void getString(String inputStr) {
this.inputStr = inputStr;
this.catchStr = new char[inputStr.length()];
}
And, setting the attribute catchStr to uninitialised.
private char[] catchStr;
The second issue is with your for loop. You start the counter at 0 and use catchStr[counter - 1] to look back on the previous character. This will not work when counter = 0 because the index will evaluate to -1.
Consider starting your counter at 1, and continue to work on the method from there. You'll need to tweak it a little to get it output the desired string.
for (int counter = 1; counter < this.inputStr.length(); counter++) {
if (catchStr[counter] != catchStr[counter - 1]) {
modifiedStr = modifiedStr + catchStr[counter];
}
}

How to insert a space in a charArray in an exact position [Java]

My problem is that I'm getting a String and I need to check if there is a space in the 4th position but starting from the end. If in this position there is not a space, I should insert it.
For example:
I get this String: TW12EF, need to get it like this: TW1 2EF
First of all I get the 4 last characters in a char array because I also need to check if they are numbers or letters.
With this method I check if there is a space:
public static boolean isSpace(){
return String.valueOf(charArray[0]).matches("[ \\t\\n\\x0B\\f\\r]");
}
charArray contains the last 4 characters of the input String
If charArray[0] wouldn't be a space, I want to insert a space in the 2nd place (charArray[1])
If there is something that I can correct in the question to make it easier to understand, just let me know and I will try to make it better for next questions.
A simple and direct solution (most likely faster than using a regular expression) is to get the 4th to the last character (if it exists), and if it isn't a white-space, insert a space at that position.
public static void main(String[] args) {
String str = "TW12EF";
int insertPos = str.length() - 4;
if (insertPos >= 0) {
char ch = str.charAt(insertPos);
if (!Character.isWhitespace(ch)) {
str = new StringBuilder(str).insert(insertPos + 1, ' ').toString();
}
}
System.out.println(str);
}
A whitespace is determined by invoking isWhitespace, which returns true for space but also tabs or line feeds, like you did in your question. The character is inserted by leveraging the StringBuilder#insert method, which is more direct that taking 2 substrings and concatenating them.
A quick, dirty regex will help :
String p = "TW12EF";
System.out.println(p.replaceAll("(.)\\s*(\\S.{2})$", "$1 $2")); // Select a character followed by 0 or more spaces and followed by 3 non-space characters. And replace multiple spaces if they exist with a single space
O/P :
TW1 2EF
Also works if there are one or more spaces after the 3rd char (from the left)
As char is a primitive data type, the comparison can be done simply with
if (charArray[0] == ' ') {
char[] temp = new char[5];
temp[0] = ' ';
for (int i = 1; i <= 4; i++) {
temp[i] = charArray[i - 1];
}
charArray = temp;
}
You could use something like:
public static void main(String[] args) {
String str = "TW12EF";
processStr(str);
}
public static final int SPACE_POS = 4, OFFSET = 1;
public static String processStr(String str)
{
if(!Character.isWhitespace(str.charAt(str.length() - SPACE_POS)))
{
str = String.format("%s %s", str.substring(0, str.length() - SPACE_POS + OFFSET), str.substring(SPACE_POS - OFFSET));
}
return str;
}
Like this?
` String s="TW12EF";
String result="";
int length=s.length();
for(int i=length-1;i>-1;i--){
if(i==length-4&&s.charAt(i)!=' '){
result+=" ";
}
result+=s.charAt(length-i-1);
}
System.out.println(result);`

Java string get latest 4 char reverse loop

I cannot figure how to obtain latest 4 char of string before zeroes
String str = "41f1f3d1f10000000000000000000000000000000000"
I want: d1f1
I've tried to revert string string than do straight loop
public static boolean checklast4digit(String risposta) {
String crc = "";
risposta = reverseIt(risposta);
for (int i = 0; i < risposta.length(); i++) {
if (risposta.charAt(i) != '0') crc = Character.toString(risposta.charAt(i + 3)) + Character.toString(risposta.charAt(i + 2)) + Character.toString(risposta.charAt(i + 1)) + Character.toString(risposta.charAt(i));
}
Log.i("Crc letto: ", crc);
return true;
}
public static String reverseIt(String source) { //Inversione stringa
int i, len = source.length();
StringBuilder dest = new StringBuilder(len);
for (i = (len - 1); i >= 0; i--) {
dest.append(source.charAt(i));
}
return dest.toString();
}
Exception:
java.lang.StringIndexOutOfBoundsException
As mentioned in the comments, you are looping too far. If you want to access charAt(i+3) you should only loop until i < risposta.length() - 3
Also, you need to break out of your loop, once you have found your result:
for(int i=0 ;i < risposta.length() - 3 ;i++){
if(risposta.charAt(i) != '0') {
crc= Character.toString(risposta.charAt(i + 3)) + Character.toString(risposta.charAt(i+2)) + Character.toString(risposta.charAt(i+1)) + Character.toString(risposta.charAt(i));
break;
}
}
Note that this only gives you a result, if you have 4 non-zero characters before the zeros.
There are many ways to improve your code, one of which would be to just remove the trailing zeroes first, then reverse the remaining string and take the first 4 chars of it.
However, to point out errors in your code...
Take a look at the values you're using to get characters. While your loop is limited to i<risposta.length(), i+3 that you're using in the line below is not - it can go up to risposta.length()+2. If oyu want to fix the code, then change the loop condition to i+3<risposta.length().
It's not elegant and can be done better, but that would solve the immediate bug in your code.
Your IndexOutOfBoundsException is caused by:
risposta.charAt(i + 3)
risposta.charAt(i+2)
risposta.charAt(i+1)
If you take a look at your for loop:
for(int i=0 ; i < risposta.length(); i++){
}
You are iterating from index 0 to risposta.length() - 1. However because you are getting the char at i+3 when i is risposta.length() - 1 it tries to access the index risposta.length() + 2 which is out of bounds.
You ned to modify your loop so you only iterate up to risposta.length() - 3
Here you have a oneliner!
String a = new StringBuilder(new StringBuilder("41f1f3d1f10000000000000000000000000000000000".split("0")[0]).reverse().toString().substring(0, 4)).reverse().toString();
And the complete code looks like this:
package nl.testing.startingpoint;
public class Main {
public static void main(String args[]) {
String a = new StringBuilder(new StringBuilder("41f1f3d1f10000000000000000000000000000000000".split("0")[0]).reverse().toString().substring(0, 4)).reverse().toString();
System.out.println(a);
}
}
result: d1f1
Alternatively, you could strip the 0's with a replaceAll and then get the last 4 chars with a substring. That makes the code pretty simple:
public static void main(String[] args) {
String str = "41f1f3d1f10000000000000000000000000000000000";
str = str.replaceAll("0*$", "");
System.out.println(str.substring(str.length()-4));
}
First of all the StringBuilder has a reverse method, which you can use to revers a string. That would simplify the reversing quite a bit.
return new StringBuilder(source).reverse().toString();
and as the others pointed out your for loop probably causes the exception, as it iterates to long.
To remove all trailing zeros (as suggested by CptBartender) you can use regex.
risposta = risposta.replaceFirst("0+$");
Then you can reverse the string (as shown above) and get the first n characters using the substring method.
reversed.substring(0, Math.min(reversed.length(), 4));
Math.min() is used to ensure there is no error if there are less than 4 characters before the zeros.

Splitting an array with commas to separate each elemnt

I have an output that comes out printing : 1 2 3 4 5
I want the output to be : 1,2,3,4,5
When I print my final array, It looks like : System.out.println(D);
What should I add to it to suit my needs.
All answers are welcome.
why not simply use Arrays.toString
public static String toString(int[] a) Returns a string representation
of the contents of the specified array. The string representation
consists of a list of the array's elements, enclosed in square
brackets ("[]"). Adjacent elements are separated by the characters ",
" (a comma followed by a space). Elements are converted to strings as
by String.valueOf(int). Returns "null" if a is null. Parameters: a -
the array whose string representation to return Returns: a string
representation of a Since:
1.5
try
System.out.println (Arrays.toString (D));
if the spaces are unwanted, then they can be replaced using
System.out.println (Arrays.toString (D).replace(" ", ""));
Replace (typeof x) with the element type of the array (or put this code in a generic function for bonus points, but it won't work for primitive types then):
StringBuilder out = (new StringBuilder());
boolean first = true;
for ((typeof x) x : D) {
if (!first) {
out.append(",")
}
out.append(x.toString());
first = false;
}
return out.toString();
You can create you own methods for printing the result, for example this one :
for (int i = 0; i < D.length; i++) {
System.out.print(D[i]);
if (i != D.length-1){
System.out.print(",");
}
}
I think you are trying to print out an array with commas instead of spaces.
for (int i = 0; i < arr.length() - 1; i++) {
System.out.print(arr[i]);
System.out.print(',');
}
System.out.println(arr[arr.length() - 1]);
You can just print out the elements of the Array singly, like this:
String output = "";
//go through all elements in D
for (int i =0;i<D.length;i++){
//add the Integer to the String
output = output+i;
//add , if not the last element
if (i<D.length-1){
output = output+",";
}
}
//Print it out
System.out.println(output);
Try this code:
If your data type is an array of integer:
int my_array={1,2,3,4,5};
for(int i=0; i < my_array.length; i++) {
System.out.print(my_array[i] + ",");//this line will print the value with a coma (,)
}
If your data type is a string;
String my_number="1 2 3 4 5";
for(int i=0; i < my_number.length; i++){
if(my_number.toCharArray()[i]!=' ')
System.out.print(my_number.toCharArray()[i]+",");
}
Or,
String my_number="1 2 3 4 5";
my_number = my_number.replace(' ', ',');//this method (replace) will replace all space(' ') by coma(',')
System.out.println(my_number);

Categories

Resources