2009-03-27 31 views
0

これは私がやろうとしていることです:私はコマンドラインからファイルを読み込んでいます。 ファイルにはデータのリストが含まれていますが、この段落の下にはそのように見えます。 私が抱えている問題はif文です。擬似コードで配列インデックスの範囲外

import java.util.*; 
import java.io.*; 

public class VehicleTest { 
    public static void main(String[] args) throws FileNotFoundException { 
     String vehicle = "vehicle"; 
     String car = "car"; 
     String americanCar = "american car"; 
     String foreignCar = "foreign car"; 
     String truck = "truck"; 
     String bicycle = "bicycle"; 

     File file = new File(args[0]); 
     Scanner input = new Scanner(file); 

     String[] autos = new String[100]; 
     ArrayList allVehicles = new ArrayList(); 


     for (int i = 0; i < autos.length; i++) { 
      autos[i] = input.nextLine(); 
     } 

     int j = 0; 
     int i = 0; 

     while (i++ < autos.length) { 
      if (vehicle.equalsIgnoreCase(autos[j++])) { 
       Vehicle v = new Vehicle(); 
       v.setOwnerName(autos[j]); 
       allVehicles.add(v); 
      }else if(car.equalsIgnoreCase(autos[j++])){ 
       Car c = new Car(); 
       c.setOwnerName(autos[j]); 
       allVehicles.add(c); 
      } 
     } 

     for(Object a: allVehicles){ 
      System.out.println(a); 
     } 
    } 
} 

これは次のようになります。

while i is less than the length of the string array 
if you see the word vehicle create a new vehicle object and add it to the arrayList. 
if you see the word car create a new car object and add it to the arrayList. 
..... 

問題私は私が使用しているコードでarrayOutOfBounds例外を取得していることです。

私はJ ++が間違っていることを理解していますが、文字列配列を繰り返し処理して各行を読み込んで適切なオブジェクトを作成する方法を教えてください。私は何をすべきかについて迷っている。助けが必要です。

foreign car 
aMarioy 
Mario's house 
(777) 777-7777 
[email protected] 
false 
black 
Italy 
4415.91 

truck 
aDougy 
Doug's house 
(123) 456-7890 
[email protected] 
30 
61234.56 
8/10/2003 

vehicle 
aRobby 
Rob's house 
(987) 654-3210 
[email protected] 

bicycle 
bTommy 
Tom's house 
(246) 810-1214 
[email protected] 
7 

truck 
bGeorge 
George's house 
(666) 666-6666 
[email protected] 
25 
51234.56 
12/4/2004 

vehicle 
bTim 
Tim's house 
(111) 111-1111 
[email protected] 

bicycle 
bJim 
Jim's house 
(555) 555-5555 
[email protected] 
5 

american car 
bJohn 
John's house 
(888) 888-8888 
[email protected] 
true 
green 
false 
true 

car 
cKen 
Ken's house 
(999) 999-9999 
[email protected] 
false 
orange 

foreign car 
cMario 
Mario's house 
(777) 777-7777 
[email protected] 
false 
black 
Italy 
4415.91 


american car 
gSam 
Sam's house 
(333) 333-3333 
[email protected] 
false 
blue 
true 
false 

答えて

6

問題のカップル:

  • あなたは両方の "if" のテストでJをインクリメントしています。私は確信していることを確認していません(正直言って、複雑なコードです)。しかし、一致を見つけたらjをインクリメントしてください。
  • iを使ったテストでは、基本的に、ファイルの終わりに達したときに停止するのではなく、ファイル内の行数と同じ数のビークルを読み込もうとします。基本的にiは必要ありません。

は、ここに1つ変更されたバージョンです:

while (j < autos.length) { 
     if (vehicle.equalsIgnoreCase(autos[j])) { 
      j++; 
      Vehicle v = new Vehicle(); 
      v.setOwnerName(autos[j++]); 
      allVehicles.add(v); 
     } else if(car.equalsIgnoreCase(autos[j])){ 
      j++; 
      Car c = new Car(); 
      c.setOwnerName(autos[j++]); 
      allVehicles.add(c); 
     } 
    } 

一度かかわらタイプを抽出するために、わずかにきれいになる - あなたは個別に比較を行うことができます。

while (j < autos.length) { 
     String type = autos[j++]; 
     if (vehicle.equalsIgnoreCase(type)) { 
      Vehicle v = new Vehicle(); 
      v.setOwnerName(autos[j++]); 
      allVehicles.add(v); 
     } else if(car.equalsIgnoreCase(type)){ 
      Car c = new Car(); 
      c.setOwnerName(autos[j++]); 
      allVehicles.add(c); 
     } 
    } 

それはまだないかなりの方法です私はそれをするだろうが、それはもっと近い...

私の次のステップは、より適切にスキャナを使用することです:

while (scanner.hasNext()) { 
    String type = scanner.nextLine(); 
    if (type.equalsIgnoreCase("vehicle")) { 
     allVehicles.add(new Vehicle(scanner)); 
    } else if (type.equalsIgnoreCase("car")) { 
     allVehicles.add(new Car(scanner)); 
    } 
    // ... 
} 

次に、Vehicle、Carなどのコンストラクタをスキャナから直接構文解析します。

次の手順は、繰り返しと構造を分離することです。

// Use a base type in real code 
private static Object parseNextVehicle(Scanner scanner) { 
    String type = scanner.nextLine(); 
    if (type.equalsIgnoreCase("vehicle")) { 
     return new Vehicle(scanner); 
    } else if (type.equalsIgnoreCase("car")) { 
     return new Car(scanner); 
    } 
    // ... throw an exception indicating an unknown vehicle type 
} 

// ... and then in the main method, use it like this: 
while (scanner.hasNextLine()) { 
    allVehicles.add(parseNextVehicle(scanner)); 
} 
+0

誰もが説明する前に、「これは代わりにしてみてください」の提案が掲載されているどのように多くの興味深いです実際のe不具合 – Tomalak

+1

@Tomalak、質問には、「私は++が間違っていることを理解していますが、文字列を繰り返し処理して、各行を読み込んで適切なオブジェクトを作成できるようにするにはどうしたらいいですか? – strager

+0

@strager:本当ですが、私はこの行が選択肢の要求であることを意図していたとは思っていません。投稿全体が「なぜこの例外を取得するのですか?」それの上に書かれています。 – Tomalak

0

独自の文で増分と減分を入れてください。これにより、ほとんどの場合、コードがわかりやすくなります。

最初のifが失敗した場合、j++が2回呼び出されます。これはおそらくあなたが望むものではありません。

私はそうのように、forループにあなたのwhileループを変換します:

for (int i = 0, j = 0; i < autos.length; ++i, ++j) { 
    if (vehicle.equalsIgnoreCase(autos[j])) { 
     // ... 

i == j場合は常に、ちょうど両方に同じ変数を使用します。

1

同じ「車両」にないすべての行(間違って)ので、約50行の後にあなたが例外を取得しますjをインクリメントします:新しい方法を紹介します。

はこれに複数の解決策があります。

  • インクリメントj度だけループあたり。
  • 行を別のArrayListに読み込みます。
  • データ構造体に行を読み込まず、読み取っているときにその行を処理します。この方法では、データのサイズからより独立しています。
1

添え字にj ++は使用しないでください。どの条件が成立しているかに応じて1回または2回ではなく、ループ全体の後で1回増分します。

おそらくより良いこれを行うには:

  • 彼らはコードを作るために行く必要がある(X = X + 1)
  • フィギュアアウトインクリメント文ですべてのあなたのインラインずつ(X ++)を交換あなたはそれが適切と思われる場合は、それが働いて得したら
  • は、プリ/ポスト増分をインライン化するために戻ってそれらを有効
  • やりたい
関連する問題