web-dev-qa-db-ja.com

NumberFormatExceptionとは何ですか?どうすれば修正できますか?

Error Message:
Exception in thread "main" Java.lang.NumberFormatException: For input string: "Ace of Clubs"
    at Java.lang.NumberFormatException.forInputString(NumberFormatException.Java:65)
    at Java.lang.Integer.parseInt(Integer.Java:580)
    at Java.lang.Integer.parseInt(Integer.Java:615)
    at set07102.Cards.main(Cards.Java:68)
C:\Users\qasim\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)

私のWhileループ:

while (response != 'q' && index < 52) {
    System.out.println(cards[index]);
    int first_value = Integer.parseInt(cards[index]);
    int value = 0;
    //Add a Scanner
    Scanner scanner = new Scanner(System.in);
    System.out.println("Will the next card be higher or lower?, press q if you want to quit");
    String guess = scanner.nextLine();
    if(cards[index].startsWith("Ace")) { value = 1; }
    if(cards[index].startsWith("2")) { value = 2; }
    if(cards[index].startsWith("3")) { value = 3; }
    //checking 4-10
    if(cards[index].startsWith("Queen")){ value = 11; }
    if(cards[index].startsWith("King")){ value = 12; }
    if(guess.startsWith("h")){
        if(value > first_value){ System.out.println("You answer was right, weldone!"); } 
        else { System.out.println("You answer was wrong, try again!"); }
    } else if(guess.startsWith("l")){
        if(value < first_value) { System.out.println("You answer as right, try again!"); }
        else { System.out.println("You answer was wrong, try again!"); }
    } else { System.out.println("Your was not valid, try again!"); }
    scanner.close();            
    index++;
}//end of while loop
19
Qasim Imtiaz
Error Message:
Exception in thread "main" Java.lang.NumberFormatException: For input string: "Ace of Clubs"
    at Java.lang.NumberFormatException.forInputString(NumberFormatException.Java:65)
    at Java.lang.Integer.parseInt(Integer.Java:580)
    at Java.lang.Integer.parseInt(Integer.Java:615)
    at set07102.Cards.main(Cards.Java:68)
C:\Users\qasim\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1

手段:

There was an error. We try to give you as much information as possible
It was an Exception in main thread. It's called NumberFormatException and has occurred for input "Ace of Clubs".
at line 65th of NumberFormatException.Java which is a constructor,
which was invoked from Integer.parseInt() which is in file Integer.Java in line 580,
which was invoked from Integer.parseInt() which is in file Integer.Java in line 615,
which was invoked from method main in file Cards.Java in line 68.

It has resulted in exit code 1

つまり、"Ace of Clubs"を解析してintにしようとしましたが、JavaはメソッドInteger.parseIntではできません。 Javaは、問題の内容を正確に示す美しいスタックトレースを提供します。探しているツールはdebuggerであり、breakpointsを使用すると選択した時点でアプリケーションの state を検査します。

解決策は、 parsing を使用する場合の次のロジックです。

if (cards[index].startsWith("Ace")) 
    value = 1;
else if (cards[index].startsWith("King"))
    value = 12;
else if (cards[index].startsWith("Queen"))
    value = 11;
...
else {
    try {
        Integer.parseInt(string.substring(0, cards[index].indexOf(" "))); 
    } catch (NumberFormatException e){
        //something went wrong
    }
}

JavaのExceptionとは何ですか?

例外は、プログラムの実行中に発生するイベントであり、プログラムの命令の通常のフローを中断します。

- ドキュメント

Integer#parseIntのコンストラクターと使用法

static NumberFormatException forInputString(String s) {
    return new NumberFormatException("For input string: \"" + s + "\"");
}

public NumberFormatException (String s) {
    super (s);
}

スタックトレースの読み方を理解するために重要です。 NumberFormatExceptionInteger#parseIntからどのようにスローされるかを見てください。

if (s == null) {
    throw new NumberFormatException("null");
}

または入力String sの形式が解析可能でない場合:

throw NumberFormatException.forInputString(s); 

NumberFormatExceptionとは何ですか?

アプリケーションが文字列を数値型のいずれかに変換しようとしたが、文字列に適切な形式がないことを示すためにスローされます。

- ドキュメント

NumberFormatExceptionextendsIllegalArgumentException。より特殊なIllegalArgumentExceptionであることがわかります。実際、引数の型は正しい(String)が、Stringの内容は数値ではない( a、b、c、d)ことを強調するために使用されます、e、fは16進数の数字と見なされ、必要な場合は有効です()。

どうすれば修正できますか?
まあ、それがスローされるという事実を修正しないでください。投げられるのはいいことです。考慮すべきことがいくつかあります。

  1. スタックトレースを読むことはできますか?
  2. StringExceptionを引き起こすnullですか?
  3. 数字のように見えますか?
  4. 「私の文字列」またはユーザーの入力ですか?
  5. 継続する

広告。 1。

メッセージの最初の行は、例外が発生したという情報と、問題の原因となったStringです。文字列は常に:の後に続き、引用符で囲まれます("some text")。最初の数行は通常NumberFormatExceptionのコンストラクター、構文解析メソッドなどであるため、最後からスタックトレースを読み取ることに興味を持つようになります。最後に、バグを作成したメソッドがあります。呼び出されたファイルとメソッドで指摘されます。行も添付されます。わかるでしょ。スタックトレースの読み方の例は上記です。

広告。 2。

見ると、"For input string:"と入力の代わりにnull not "null")があります。つまり、null参照を数値に渡そうとしました。 。実際に0またはその他の数値として処理する場合は、StackOverflowに関する別の投稿に興味があるかもしれません。 here が利用可能です。

予期しないnullsの解決の説明は、StackOverflowスレッドで詳細に説明されています NullPointerExceptionとは何ですか。どうすれば修正できますか

広告。 3。

:に続いて引用されているStringがあなたの意見では数字のように見える場合、システムがデコードしない文字や見えない空白があるかもしれません。 " 6"は、"123 "と同様に解析できないことは明らかです。スペースが原因です。しかし、String"6"のように見えることもありますが、実際にはその長さは表示可能な桁数より大きくなります。

この場合、debuggerまたは少なくともSystem.out.printlnを使用して、解析しようとしているStringの長さを出力することをお勧めします。桁数よりも多く表示される場合は、stringToParse.trim()を解析メソッドに渡してみてください。動作しない場合は、:の後の文字列全体をコピーし、オンラインデコーダーを使用してデコードします。すべてのキャラクターのコードが表示されます。

StackOverflowで最近発見した1つのケースもあります。入力が数字のように見えることがわかります。 "1.86"で、これらの4文字のみが含まれていますが、エラーはまだ存在しています。整数を解析できるのは、#Integer#parseInt#のみです。 10進数の解析には、Double#parseDoubleを使用する必要があります。

もう1つの状況は、数字の桁数が多い場合です。大きすぎるか小さすぎてintまたはlongに収まらない場合があります。 new BigDecimal(<str>)を試してください。

広告。 4。

最後に、ユーザーが「abc」を数値文字列として入力している状況を避けることはできない、ということに同意する場所に行きます。どうして?彼ができるから。幸運な場合、それは彼がテスターまたは単にオタクだからです。悪い場合には、攻撃者です。

今何ができますか?さて、Javaはtry-catchを提供してくれます。

try {
    i = Integer.parseInt(myString);
} catch (NumberFormatException e) {
    e.printStackTrace();
    //somehow workout the issue with an improper input. It's up to your business logic.
}
37
xenteros

NumberFormatExceptionとは何ですか?

この例外は、アプリケーションがstringを数値型のいずれかに変換しようとしたが、stringが適切な形式ではないことを示すためにスローされます。

あなたの場合、スタックトレースによると、この例外は Integer.parseInt(String) によってスローされました。つまり、提供されたStringには解析可能なintegerが含まれていません。スタックトレースによると、String "Ace of Clubs"を解析しようとしたためです。整数のString表現ではないため機能しない整数。

修正方法

最も簡単で一般的な方法は、例外NumberFormatExceptionをキャッチすることです

_int value = -1;
try {
    value = Integer.parseInt(myString);
} catch (NumberFormatException e) {
    // The format was incorrect
}
_

動作しますが、例外をキャッチするには時間がかかります。呼び出しスタックを作成してExceptionを作成する必要があるため、例外をキャッチするには時間がかかります。さらに、例外を適切に管理する必要がありますが、これは必ずしも明らかではありません。

または、StringmatchesIntegerであるかどうかを最初に確認するために_regular expression_を使用できますが、簡単に使用できるため、かなりエラーが発生しやすくなります間違った_regular expression_。


あなたの場合、Stringを扱う代わりに、より多くのOOアプローチを使用する必要があります。たとえば、classまたはenumを使用して表すことができます単純なStringを使用する代わりにカードを作成します。すでに気づいているように、エラーが発生しやすいためです。

したがって、カードに専用クラスを使用することにした場合、コードは次のようになります。

_public class Card {

    private final Rank rank;
    private final Suit suit;

    public Card(final Rank rank, final Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public Rank getRank() {
        return this.rank;
    }

    public Suit getSuit() {
        return this.suit;
    }
}
_

カードのスーツとランクについては、既存のランクとスーツの量が限られているため、enumを使用できます。

_public enum Rank {
    ACE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), HEIGHT(8),
    NINE(9), TEN(10), JACK(11), QUEEN(12), KING(13);

    private final int value;

    Rank(final int value) {
        this.value = value;
    }

    public int getValue() {
        return this.value;
    }
}

public enum Suit {
    SPADE, HEART, DIAMOND, CLUB
}
_

cardsは、Cardの配列ではなく、Stringの配列になり、次のように初期化できます。

_Rank[] ranks = Rank.values();
Suit[] suits = Suit.values();
Card[] cards = new Card[ranks.length * suits.length];
for (int i = 0; i < ranks.length; i++) {
    for (int j = 0; j < suits.length; j++) {
        cards[i * suits.length + j] = new Card(ranks[i], suits[j]);
    }
}
_

カードの配列をシャッフルする必要がある場合は、次の手順に進むことができます(配列の代わりにListのカードを使用することにした場合は、単にCollections.shuffle(list)を使用してください)

_List<Card> allCards = Arrays.asList(cards);
Collections.shuffle(allCards);
allCards.toArray(cards);
_

その後、cards[index].getRank().getValue()を使用して、例外を取得するリスクを負うことなく、カードの値に直接アクセスできます(適切なインデックスを使用しない場合はIndexOutOfBoundsExceptionを除きます)。

10
Nicolas Filotto

cards[]String配列であり、変換しようとしていますAce of Clubs整数

int first_value = Integer.parseInt(cards[index]);
6
Vivek G
Java.lang.NumberFormatException 

number文字列ではない入力を解析しようとすると発生します。

あなたの場合、文字列(数値を持たない)を整数として解析しようとしています。不可能なため、NumberFormatException例外が発生しました。

int first_value = Integer.parseInt(cards[index]);//cards[index] value should be //number string "123" not "abc"
2
Rajesh Gopu

NumberFormatExceptionは、Javaが「Stringをintに変換しようとしましたが、できませんでした」と言わなければならない方法です。

あなたの例外トレースであなたは読むことができます

Exception in thread "main" Java.lang.NumberFormatException: For input string: "Ace of Clubs"
    at Java.lang.NumberFormatException.forInputString(NumberFormatException.Java:65)
    at Java.lang.Integer.parseInt(Integer.Java:580)
    at Java.lang.Integer.parseInt(Integer.Java:615)
    at set07102.Cards.main(Cards.Java:68)

基本的に、コードの68行目でInteger.parseIntメソッドを呼び出し、パラメーターとして「Ace of Clubs」を渡します。このメソッドは、Stringとして表される整数値を想定しています。 「4」。したがって、「Ace of Clubs」は整数ではないため、メソッドはNumberFormatExceptionをスローします。

2
jmlotero

ループのために私を投げた非常に最初のこと(しゃれは意図されていません)は、値を0から52にする必要があるときに1から13に制限していました。また、ロジックでは、値は常に高くなりました。より良いアプローチは、数値ジェネレーターを使用することです。数値ジェネレーター(またはJava Random))を使用したコードを次に示します。

public static void main(String[] args) {

String[] cards = { "Ace of Clubs", "1 of Clubs", "2 of Clubs",
        "3 of Clubs", "4 of Clubs", "5 of Clubs", "6 of Clubs",
        "7 of Clubs", "8 of Clubs", "9 of Clubs", "10 of Clubs",
        "Queen of Clubs", "King of Clubs", "Ace of Diamonds",
        "1 of Diamonds", "2 of Diamonds", "3 of Diamonds",
        "4 of Diamonds", "5 of Diamonds", "6 of Diamonds",
        "7 of Diamonds", "8 of Diamonds", "9 of Diamonds",
        "10 of Diamonds", "Queen of Diamonds", "King of Diamonds",
        "Ace of Hearts", "1 of Hearts", "2 of Hearts", "3 of Hearts",
        "4 of Hearts", "5 of Hearts", "6 of Hearts", "7 of Hearts",
        "8 of Hearts", "9 of Hearts", "10 of Hearts",
        "Queen of Hearts", "King of Hearts", "Ace of Spades",
        "1 of Spades", "2 of Spades", "3 of Spades", "4 of Spades",
        "5 of Spades", "6 of Spades", "7 of Spades", "8 of Spades",
        "9 of Spades", "10 of Spades", "Queen of Spades",
        "King of Spades" };

Scanner scanner = new Scanner(System.in);
Random Rand = new Random();
String response = "";
int index = 0;
int value = 0;  
while (!response.equals("q") && index < 52) {

    // set next card value based on current set of cards in play
    if (cards[index].endsWith("Clubs")) {
        value = Rand.nextInt(12);
    }
    if (cards[index].endsWith("Diamonds")) {
        value = Rand.nextInt(12) + 13;
    }
    if (cards[index].endsWith("Hearts")) {
        value = Rand.nextInt(12) + 26;
    }
    if (cards[index].endsWith("Spades")) {
        value = Rand.nextInt(12) + 39;
    }

    // display card too user (NOTE: we use the random number not the index)
    System.out.println("Card is: " + cards[value]);

    // ask user what well the next card be
    System.out.println("Will the next card be higher or lower?, press q if you want to quit");
    response = scanner.nextLine();

    // display if user was right (NOTE: compared the random number to the current index)
    // ignore incorrect response and just continue
    if ((value > index && response.startsWith("h")) || (value < index && response.startsWith("l"))) {
        System.out.println("You answer was right, well done!");
    } else {
        System.out.println("You answer was wrong, try again!");
    }

    // continue loop
    index++;
}
}

NumberFormatExceptionについては、Nicolas Filottoがそれをうまく説明できたと思います。

1
thekodester

NumberFormatExceptionは、Integer.parseInt()が文字列を数値に変換できなかったことを意味します。

次の2つのオプションのいずれかをお勧めします。

  1. カードをname(string)/ value(int)コンボとしてカプセル化します。値を使用して比較を行い、名前を使用して情報をユーザーに提示します。 _Cards[]_は、文字列ではなくカードのリストになります。

  2. 自分で文字列を解析します。 if(cards[index].startsWith("Ace")) { value = 1; }ビットを使用して既に実行しているため、これは簡単かもしれません。これらをCardToInt()(または何でも)と呼ばれる関数に移動し、Integer.parseInt()の代わりにその関数を使用できます。

1
Andrew Tofelt
int first_value = Integer.parseInt(cards[index]); 

上記の声明を書いている間に、「クラブのエース」を数字として解析しようとしています。

次の方法を使用して、文字列を整数として解析できるかどうかをテストできます。

boolean tryParseInt(String value) {  
     try {  
         Integer.parseInt(value);  
         return true;  
      } catch (NumberFormatException e) {  
         return false;  
      }  
}

あなたの質問に関して、NumberFormatExceptionとは何ですか:アプリケーションが文字列を数値型のいずれかに変換しようとしたが、文字列が適切な形式ではないことを示すためにスローされます。 (参照- http://docs.Oracle.com/javase/7/docs/api/Java/lang/NumberFormatException.html

1
roopaliv

例外はコードにあり、文字列を整数に変換します:

int first_value = Integer.parseInt(cards[index]);

stringを"Ace of Clubs"として渡す場合、整数として変換することはできないため、Number Format Exceptionがスローされます。使用できます

try {
     ....
     // Your Code
     ....
    }
catch(NumberFormatException e)
{
    e.getMessage();  //You can use anyone like printStackTrace() ,getMessage() to handle the Exception
}
0
Anands23