我是java编程的新手,我尝试了一个示例代码来获取两位数的输入并打印该数字的措辞。
public class ReadNumberInWord {
public Integer number;
public ReadNumberInWord() {
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the number to read out : ");
try {
number = userInput.nextInt();
readNumber();
} catch (Exception e) {
System.out.println("Please enter an integer");
new ReadNumberInWord();
}
}
public void readNumber() {
System.out.println("Entered number is : " + number);
int numSize = number.toString().length();
System.out.println("number size is : " + numSize);
switch (numSize) {
case 1:
sizeOne();
break;
case 2:
sizeTwo();
break;
case 3:
sizeThree();
break;
case 4:
sizeFour();
break;
default:
System.out.println("Enter number of four digit or less ");
new ReadNumberInWord();
break;
}
}
private void sizeFour() {
System.out.println("Number in words : " + numberCheck(number.toString()));
}
private void sizeThree() {
String[] sizeThree = number.toString().split("");
System.out.println(sizeThree[0]);
System.out.println(sizeThree[1]);
System.out.println(sizeThree[2]);
for (int i = 0; i <= sizeThree.length - 1; i++) {
System.out.println(sizeThree[i]);
}
System.out.println("Number in words : " + numberCheck(number.toString()));
}
private void sizeTwo() {
String[] sizeTwo = number.toString().split("");
//System.out.println(sizeTwo[0]);
//System.out.println(sizeTwo[1]);
String wordsString1 = "";
ArrayList<String> wordsArray = new ArrayList<String>();
for (int i = 0; i <= sizeTwo.length - 1; i++) {
System.out.println(sizeTwo[i]);
String words = numberCheck(sizeTwo[i]);
wordsArray.add(words);
}
for (String w : wordsArray) {
wordsString1 += w + "\t";
}
System.out.println("Number in words : " + wordsString1);
}
private void sizeOne() {
System.out.println("Number in words : " + numberCheck(number.toString()));
}
public String numberCheck(String numb) {
int num = Integer.parseInt(numb);
switch (num) {
case 0:
return "zero";
case 1:
return "one";
case 2:
return "two";
case 3:
return "three";
case 4:
return "four";
case 5:
return "five";
case 6:
return "six";
case 7:
return "seven";
case 8:
return "eight";
case 9:
return "nine";
case 10:
return "ten";
default:
return "unknown";
}
}
public static void main(String[] args) {
new ReadNumberInWord();
}
}
在上面的代码中,如果我输入两位数字作为78,它应该打印七八。但是,这不适用于此。相反,我得到了例外。请帮我解决。
答案 0 :(得分:3)
在调试时,堆栈跟踪是非常有用的信息,如果遇到意外的异常但忽略堆栈跟踪,则忽略此信息。如果你打印了异常的堆栈跟踪,你会看到这个:
Enter the number to read out :
78
Entered number is : 78
number size is : 2
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at ReadNumberInWord.numberCheck(ReadNumberInWord.java:74)
at ReadNumberInWord.sizeTwo(ReadNumberInWord.java:58)
at ReadNumberInWord.readNumber(ReadNumberInWord.java:26)
at ReadNumberInWord.<init>(ReadNumberInWord.java:13)
at ReadNumberInWord.main(ReadNumberInWord.java:94)
这清楚地表明Integer.parseInt()
,通过numberCheck()
,使用空字符串""
进行输入,这不是一个有效的整数,会导致Integer.parseInt()
抛出你看到的例外。
现在你需要找出正在发生的为什么。您知道传递给parseInt()
的字符串直接来自numberCheck()
参数,因此这意味着numberCheck()
传递一个空字符串。既然你知道输入来自sizeTwo
中的sizeTwo()
数组,那么一个好的开始就是在那里打印那个数组的内容:
System.out.println(Arrays.toString(sizeTwo));
这样做,你会看到:
[ , 7, 8 ]
第一个空元素是提示。以这种方式使用split是不太对的,从技术上讲,输入字符串以&#34; empty&#34;开头。字符串,你最终得到它(例如在":7:8"
上分割:
)。您必须使numberCheck()
忽略空字符串,或者找到将字符串拆分为数字的其他方法。前者是对问题根本原因的创可贴(请记住:你的实际意图是不在数字列表中包含任何空字符串),所以我们将关注后者。
一种选择是将数字转换为String
(跳过String[]
事物),然后转换为char
数组,例如:
char[] digits = number.toString().toCharArray();
然后,您可以使用char
代替String
。另一个选择是在循环中使用substring()
,例如:
String numberstr = number.toString();
for (int n = 0; n < numberstr.length(); ++ n) {
String digit = number.substring(n, 1);
...
}
当然,拥有这个字符串中间人并不是必需的,你可以用算术来做:
for (int n = (int)Math.log10(number); n >= 0; -- n) {
int digit = (number / (int)Math.pow(10, n)) % 10;
System.out.println(digit);
}
或反过来但不依赖于浮点计算:
int temp = number;
while (temp) {
digit = temp % 10;
temp /= 10;
System.out.println(digit);
}
您的代码可以通过许多其他方式进行清理和大大简化(例如Richard Miskin在评论中暗示,您真的需要解析int
吗?)但我认为以上涵盖了您当前问题的根源。
至于错误处理本身,我建议您只使用Scanner.next()
来读取字符串,然后您可以使用Integer.parseInt()
来解析它,如果您看到NumberFormatException
,请再次询问。这将适当地使用异常,并且使用next()
而不是nextInt()
将令牌从流中拉出,即使它是无效的int(让您继续请求输入)。例如:
Scanner userInput = new Scanner(System.in);
System.out.println("Enter the number to read out : ");
while (true) {
try {
number = Integer.parseInt(userInput.next());
break;
} catch (NumberFormatException x) {
System.out.println("Please enter a valid integer");
}
};
请注意以下几个关键概念:
NumberFormatException
,而不是Exception
)。有道理因为:NumberFormatException是我们试图处理的唯一问题。您当前的实现设置了一个递归堆栈,还有一些其他问题。
答案 1 :(得分:1)
问题在于:
String[] sizeTwo=number.toString().split("");
当数字为“78”时,它产生数组[“”,“7”,“8”],而不是[“7”,“8”]。 您应该以不同方式将字符串拆分为数字(或忽略始终为空字符串的第一个标记)。
split(..)接受一个正则表达式,指定哪些模式被视为标记分隔符。在您的情况下,我发现以下正则表达式很有用:
String[] sizeTwo=number.toString().split("(?<=\\d)(?=\\d)");
它要求分隔符为空字符串,前后跟一个数字(使用一个名为positive lookbehind和positive lookahead的功能)
答案 2 :(得分:1)
你正在从终端读取字符Integer
,然后不得不跳过箍将其转换为字符数组以便进一步处理,这似乎有点奇怪。通过阅读String
,验证String
符合您的要求,然后处理String
中的每个字符,可以简化逻辑。
我还有其他一些变化:
number
不需要是成员变量,您只需将其作为参数传递给每个方法调用,String
,则无需将toCharArray()
的各个元素转换回switch语句的整数。以下示例适用于String
而不是Integer
。
import java.util.Scanner;
public class ReadNumberInWord {
public ReadNumberInWord() {
final Scanner userInput = new Scanner(System.in);
System.out.println("Enter the number to read out : ");
boolean success = false;
// Keep looping until the correct input is supplied.
while (!success) {
final String number = userInput.nextLine();
if (validNumber(number)) {
readNumber(number);
success = true;
}
}
}
/**
* @param number
* the String to check.
* @return <code>true</code> if and only if number is less than 5 characters
* long and can be parsed as an integer.
*/
private boolean validNumber(final String number) {
boolean returnValue = false;
try {
Integer.parseInt(number);
if (number.length() <= 4) {
returnValue = true;
} else {
System.out.println("Enter number of four digit or less ");
}
} catch (final NumberFormatException e) {
System.out.println("Please enter an integer");
}
return returnValue;
}
/**
* When supplied a String that represents an integer this method writes out
* each digit as a word to stdout.
*
* @param number
* a String that represents an integer
*/
public void readNumber(final String number) {
System.out.println("Entered number is : " + number);
final int numSize = number.length();
System.out.println("number size is : " + numSize);
final char[] chars = number.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.print(numberCheck(chars[i]));
if (i < chars.length - 1) {
System.out.print('\t');
} else {
System.out.println();
}
}
}
/**
* @param num
* a character that represents one of the numbers 0-9
* @return the word representing the supplied number e.g. zero, one etc
*/
public String numberCheck(final char num) {
switch (num) {
case '0':
return "zero";
case '1':
return "one";
case '2':
return "two";
case '3':
return "three";
case '4':
return "four";
case '5':
return "five";
case '6':
return "six";
case '7':
return "seven";
case '8':
return "eight";
case '9':
return "nine";
default:
return "unknown";
}
}
public static void main(final String[] args) {
new ReadNumberInWord();
}
}