2015-01-21 2 views
1

저는 Java 프로그래밍에 익숙하지 않고 문자열의 공백을 %20으로 바꾸고 마지막 String을 반환하는 코드를 작성했습니다. 다음은 문제의 코드입니다. 프로그래밍에 익숙하지 않으므로 내가 잘못한 것을 말해주십시오. 내 하찮은 영어 실력에 죄송하다는 말씀을 드리고 싶습니다.배열 인덱스가 바운드 예외를 반환하는 문자 배열

package Chapter1; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 


public class Problem4 { 
public char[] replaceSpaces(char[] str_array, int length) 
{ 
    int noOfSpaces=0,i,newLength; 
    for(i=0;i<length;i++) 
    { 
     if(str_array[i]==' ') 
     { 
      noOfSpaces++; 
     } 

     newLength = length + noOfSpaces * 2; 
     str_array[newLength]='\0'; 
     for(i=0;i<length-1;i++) 
     { 
      if(str_array[i]==' ') 
      { 
       str_array[newLength-1]='0'; 
       str_array[newLength-2]='2'; 
       str_array[newLength-3]='%'; 
       newLength = newLength-3; 
      } 
      str_array[newLength-1]=str_array[i]; 
      newLength = newLength - 1; 

     } 
    } 

    return str_array; 

} 
public static void main(String args[])throws Exception 
{ 
    BufferedReader reader = new BufferedReader(new  InputStreamReader(System.in)); 
    System.out.println("Please enter the string:"); 
    String str = reader.readLine(); 
    char[] str_array = str.toCharArray(); 
    int length = str.length(); 
    Problem4 obj = new Problem4(); 
    char[] result = obj.replaceSpaces(str_array, length); 
    System.out.println(result); 
    } 

} 

는하지만 다음과 같은 오류 얻을 :

Please enter the string: 
hello world 
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 
at Chapter1.Problem4.replaceSpaces(Problem4.java:19) 
at Chapter1.Problem4.main(Problem4.java:46) 

답변

1

Java 배열은 동적이 아니며 (Object 인스턴스이며 변경되지 않는 필드 length입니다.) 그들은 길이를 필드로 저장하기 때문에 '\0'이 종료되지 않았 음을 알아야합니다. 이러한 종결자를 추가하려고하면 인덱스가 경계 밖으로 벗어납니다 (Exception). 메서드가 인스턴스 필드 나 메서드에 액세스하지 못하는 것 같습니다. 그래서 정적으로 만들 것입니다. 그런 다음 StringBuilderfor-each loop을 사용할 수 있습니다.

public static char[] replaceSpaces(char[] str_array) { 
    StringBuilder sb = new StringBuilder(); 
    for (char ch : str_array) { 
     sb.append((ch != ' ') ? ch : "%20"); 
    } 
    return sb.toString().toCharArray(); 
} 

같은 뭔가 그런 @Arvindhere에 의해 제안 당신이 String str = reader.readLine().replace(" ", "+"); 또는 replaceAll(" ", "%20")을 사용할 수 있습니다, 마지막으로

char[] result = replaceSpaces(str_array); 

과 같이 호출.

P. 마지막으로 result 전화를 받으려면 print으로 전화를 수정해야합니다.

System.out.println(Arrays.toString(result)); 

또는

System.out.println(new String(result)); 

char[]

String 및 Java 배열 (실망) 그래서 당신은 Object에서 하나를 얻을 수 있습니다 toString() 우선하지 않습니다하지 않습니다.

2

어떻게 String.replaceAll() 사용에 대한 :

String str = reader.readLine(); 
str = str.replaceAll(" ", "02%"); 

샘플 code here

편집 :

문제는 라인 19에 있습니다 :

여기
str_array[newLength]='\0';//<-- newLength exceeds the char array size 

배열 크기는 StringBuilder, StringBuffer 등은 작은 작업의 크기에 대한 걱정없이 새로운 String를 구축하는 데 사용할 수있는 고정 즉 정적이다.

+0

"% 20"(또는'+')이어야합니다. URL 인코딩 된 공간입니다. –

0

newLength의 값이 str_array보다 커서이 라인의 예외는 발생합니다. str_array[newLength]='\0';입니다.

배열 크기를 정의한 후에는 늘릴 수 없습니다. 그래서 대체 솔루션을 시도하십시오.

char[] str_array1=Arrays.copyOf(str_array, str_array.length+1); 
str_array1[newLength]='\0'; 

당신은 세 문자 %20와 함께 하나의 문자 를 교체하려고 import java.util.Arrays;

+0

그래서 어떻게 내 길이가 newLength보다 커지나요? – fahadkaleem

+0

arrayize를 정의한 후에는 arrayize를 늘릴 수 없으므로 대체 배열은 이전 배열의 1만큼 크기가 증가 된 새 배열을 선언 할 수 있습니다. 다음은 그 예입니다. char [] str_array1 = Arrays.copyOf (str_array, str_array.length + 1); str_array1 [newLength] = '\ 0'; – Karthikeyan

+0

@ Karthikeyan 이제 Java로 배열을 종료하는 중입니다. 포인터가 아닙니다! –

0

please tell me what I did wrong

새로운 패키지를 가져올 것을 잊지 마세요. 배열은 고정 길이이기 때문에 불가능합니다.

따라서 char[]을 새로 할당하고 str_array의 문자를 새 배열에 복사해야합니다.

for (i = 0; i < length; i++) { 
    if (str_array[i] == ' ') { 
     noOfSpaces++; 
    } 
} 

newLength = length + noOfSpaces * 2; 
char[] newArray = new char[newLength]; 
// copy characters from str_array into newArray 
2

당신이보고 싶어한다고 가정하면 어떤 접근 방식을 구현하는 대신 완전히 다른 접근 방식을 찾을 때 당신이 만든 실수 : 지적 한 바와 같이

이 이

(1) 번 배열이 할당 된 그 크기는 변경할 수 없습니다. 귀하의 방법은 매개 변수로 str_array 걸리지 만 결과 배열은 str_array보다 클 수 있습니다. 따라서 str_array 길이를 변경할 수 없기 때문에 str_array을 사용하는 대신 결과를 저장할 새 배열을 할당해야합니다. newLength을 정확하게 계산했습니다. 그 크기의 새로운 배열을 할당 : 엘리엇은 지적

char[] resultArray = new char[newLength]; 

(2), 자바 문자열 \0 터미네이터가 필요하지 않습니다. 어떤 이유에서든 끝에 \0 문자가있는 배열을 만들려는 경우 여분의 문자를 계산하기 위해 계산 된 newLength에 1을 더해야합니다.

(3) 실제로 결과 배열을 뒤로 생성하고 있습니다. 그것이 의도적인지 나는 모른다.

 if(str_array[i]==' ') 
     { 
      str_array[newLength-1]='0'; 
      str_array[newLength-2]='2'; 
      str_array[newLength-3]='%'; 
      newLength = newLength-3; 
     } 
     str_array[newLength-1]=str_array[i]; 
     newLength = newLength - 1; 

i 문자열의 첫 번째 문자로 시작하여 위쪽으로 이동합니다. 문자열 (newLength)의 마지막 문자로 시작하여 뒤로 이동하는 문자를 채 웁니다. 그것이 당신이 의도 한 것이라면, 당신의 질문에서 분명하지 않았습니다. 출력이 "dlrow%20olleh"이 되길 원 했습니까?

(4) 가 뒤로 이동하려는 않은 경우, 다음 공간 (뒤로) 문자열에 %20을 넣어 입니다하지만 그것은 또한 결과에 공간을두고 함께 위의 코드가 무엇을. 입력 문자가 공백 인 경우 입력 문자를 결과에 복사하는 두 행을 실행하지 않도록해야합니다. 따라서 else을 추가해야합니다. (결과가 계산 된 것보다 더 많은 문자를 넣으려고하기 때문에이 문제는 범위를 벗어난 오류가 될 수 있습니다.) 실제로 빌드하려고해도 else이 있어야합니다. 문자열은 전달하고 앞으로 나아갈 수 있도록 논리를 변경해야합니다.