/*
实现记账收入和支出
可以查看记账的结果
原来的基础金额是10000元
*/
主程序代码
class FamilyAccount{
public static void main(String[] args){
boolean isFlag = true;//用来退出循环的
double basic = 10000;//基础金额
String details ="收支\t账户金额\t收支金额\t说明";//用于记录收支情况
while(isFlag){
//主页面
System.out.println("-------------------家庭收支记账软件-------------------");
System.out.println(" ");
System.out.println(" 1 收支明细");
System.out.println(" 2 登记收入");
System.out.println(" 3 登记支出");
System.out.println(" 4 退出 ");
System.out.print(" 请选择(1-4):");
//定义一个变量key保存输入的数字
char key = Utility.readMenuSelection();
//通过switch-case来分块处理4个功能
switch(key){
case '1':{
System.out.println("-------------------当前收支明细记录------------------- ");
System.out.println(" ");
System.out.println(details);
System.out.println(" ---------------------------------------------------");
System.out.println(" ");
break;
}
case '2':{
System.out.print("本次收入金额:");
int moneyIn = Utility.readNumber();
System.out.print("本次收入说明:");
String infIn = Utility.readString();
//处理金额
basic += moneyIn;
//处理收支情况,注意换行
details += "\n" + "收入\t" + basic + "\t\t" + moneyIn + "\t\t" + infIn+ "\n" ;
System.out.println("----------------------登记完成----------------------- ");
System.out.println(" ");
break;
}
case '3':{
System.out.print("本次支出金额:");
int moneyOut = Utility.readNumber();
System.out.print("本次支出说明:");
String infOut = Utility.readString();
//处理金额
basic -= moneyOut;
//处理收支情况,注意换行
details += "\n" + "支出\t" + basic + "\t\t" + moneyOut + "\t\t" + infOut + "\n" ;
System.out.println("----------------------登记完成----------------------- ");
System.out.println(" ");
break;
}
case '4':{
System.out.print("确认是否退出(Y/N): ");
//用一个变量isGo来存储是否退出
char isGo = Utility.readConfirmSelection();
if(isGo == 'Y'){
System.out.println("再见!!!");
isFlag = false;
}
}
}
}
}
}
用到的工具包Utility.java(转载他人的,侵权请联系我。)的开源代码如下:
import java.util.Scanner; //导入Scanner包,因为工具类中使用到了输入的相关方法
public class Utility {
//这个是自定义用来调用的工具类,故不需要在此定义main()语句了
private static Scanner scanner = new Scanner(System.in); //Private 变量只能在包含其声明的模块中使用
/*
定义一个readKeyBoard函数,用于从键盘读取参数限制长度的一行内容
*/
private static String readKeyBoard(int limit) {
String line = "";
while (scanner.hasNext()) {
/*
Scanner类中的hasNext方法读取的是boolean型的值,用于检测输入是否还有其他单词,有则真无则假
官方解释:当执行到hasNext()时,它会先扫描缓冲区中是否有字符,有则返回true,继续扫描。
直到扫描为空,这时并不返回false,而是将方法阻塞,等待你输入内容然后继续扫描。
*/
line = scanner.nextLine(); //将从键盘上读取到的内容赋给line,为字符串类型
if (line.length() < 1 || line.length() > limit) { //当输入字符串长度小于1或输入字符串长度超过参数限制时执行
System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
continue; //再次执行循环来读取键盘输入的有意义的值
}
break; //当读取到的字符串符合要求则终止循环,执行循环外的下一条语句返回字符串
}
return line; //返回读取到的指定长度内的字符串字面量
}
/*
用于界面菜单的选择。该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则该方法将读取到的合法键入字符返回。
*/
public static char readMenuSelection() {
char c; //定义一个字符型变量来存储选择
//无限循环for,直到读取到合法的键入字符
for ( ; ; ) {
String str = readKeyBoard(1); //调用同类下的readKeyBoard方法来读取一个键盘中输入的字符串,并赋给str
c = str.charAt(0); //调用java.lang.String类下的charAt方法,用来返回第零个位置的代码单元,即str的首位字符
if (c != '1' && c != '2' && c != '3' && c != '4') {
System.out.print("选择错误,请重新输入:");
} else break; //若读取到的字符合法,则跳出无限循环并执行下面一条语句返回读取到的合法选择
}
return c;
}
/*
用于收入和支出金额的输入。该方法从键盘读取一个不超过4位长度的整数,并将其作为方法的返回值。
*/
public static int readNumber() {
int n;
for ( ; ; ) {
String str = readKeyBoard(4);
/*
try-catch语句块:
try-catch语句是抛出异常的语句。
*/
try { //执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容
n = Integer.parseInt(str);
/*Integer.parseInt()是把()里的内容转换成整数。
Integer.parseInt(String)遇到一些不能被转换为整型的字符时,会抛出异常
若抛出异常,则执行catch语句块中的语句
*/
break;
} catch (NumberFormatException e) {
//除非try里面执行代码发生了异常,否则这里的代码不会执行
System.out.print("数字输入错误,请重新输入:");
}
}
return n;
}
/*
用于收入和支出说明的输入。该方法从键盘读取一个不超过8位长度的字符串,并将其作为方法的返回值。
*/
public static String readString() {
String str = readKeyBoard(8); //调用同类下的readKeyBoard方法并将读取到的字符串赋给str
return str;
}
/*
用于确认选择的输入。该方法从键盘读取‘Y’或’N’,并将其作为方法的返回值。
*/
public static char readConfirmSelection() {
char c;
for ( ; ; ) {
String str = readKeyBoard(1).toUpperCase();
//toUpperCase用于返回一个新字符串,将原始字符串的小写字母改为大写
c = str.charAt(0); //charAt用于返回给定位置(0为第一个位置)的代码单元
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("选择错误,请重新输入:");
}
}
return c;
}
}
运行结果: