项目家庭记账程序


前言

经过一段时间的基础学习,做一个简单的家庭记账程序。


要求

在这里插入图片描述

代码及记录

主界面

在这里插入图片描述
注:有参考
为了方便使用Scanner,声明为私有静态对象,这个类的所有方法都可以使用,还有起始的基本金和程序的收支进账的记录。这里使用二维数组对收支记录进行存储数据,注意输入的数据类型。用户在使用程序时,主界面除非退出都会在操作完毕后显示,因此用一个死循环在主界面。输入的数字为string类型。switch语句对输入的数字进行判断,然后调用相应的方法。

public class Utility {
    //私有静态对象,每个方法都可使用
    private static Scanner sc=new Scanner(System.in);
    private static int sumMoney=10000;//起始的生活基本金
    private static int count=0;//记录
    public static void main(String[] args) {
        String[][] arr=new String[10][4];//只有10条记录
        boolean flag=true;

        while(flag){
             //扩容
            String[][] arr1 = expandArray(arr);//创建一个新的数组进行接收
            arr = arr1;//进行数组替换
            
            System.out.println("-----------------家庭收支记账软件-----------------");
            System.out.println();
            System.out.println("                  1 收支明细");
            System.out.println("                  2 登记收入");
            System.out.println("                  3 登记支出");
            System.out.println("                  4 退 出");
            System.out.println();
            System.out.print("请选择(1-4):");
            String num=sc.next();
            char b1 = readMenuSelection(num);


            switch(b1){
                case '1':
                    readInfo(arr);
                    break;
                case '2':
                    addRecord(arr);
                    break;
                case '3':
                    reduceRecord(arr);
                    break;
                case '4':
                    boolean b=quitSystem();
                    if(b==true){
                        flag=false;
                    }else{
                        break;}
            }
        }

    }

判断菜单输入的选择是否合法

要对菜单选择进行判断,这里声明一个char类型的变量c,获取字符串的第一个字符,n.charAt()括号里是索引,标明字符串的第几个字符。如果没有按照1-4输入,就提示重新输入,声明一个新变量接收数据,将其赋值给变量n,接着判断,直到输入正确为止,最终返回c。

public static char readMenuSelection(String n){
        char c;
        //创建死循环
        while(true){
           c=n.charAt(0);//获取字符串第一个字符
            //判断是否按照1-4输入
           if(c != '1' && c != '2' && c != '3' && c != '4' ){
               System.out.println("输入数字错误,请按照提示正确输入:");
               String n1 = sc.next();
               n = n1;//新输入赋值给n,直到符合提示退出循环
           }else break;
        }
        return c;
    }

查看收支明细

首先要有收入支出的记录,也就是要判断二维数组是否为空,为空给出提示,不为空就进行查询操作。二维数组遍历需要两个for循环,查询第一列中为"收入"和"支出"的数据,并且格式化输出,运用到String.format。

//查看收支明细
    public static void readInfo(String[][] arr){
        //判断二维数组是否为空,为空给出提示,不为空进行查询操作
        if(arr[0][0]==null){
            System.out.println("没有收支记录,账户余额为:10000元");
        }else{
            System.out.println("收支\t\t账户总金额\t\t收支金额\t\t说  明");
            for(int i=0;i<arr.length;i++){
                for(int j=0;j<arr[i].length;j++){
                    if(arr[i][j]!=null){
                        if(arr[i][0]=="收入"){
                            System.out.println(String.format("%-6s %-15s +%-11s %-8s",arr[i][j],arr[i][1],arr[i][2],arr[i][3]));
                            break;
                        }else{
                            System.out.println(String.format("%-6s %-15s -%-11s %-8s",arr[i][j],arr[i][1],arr[i][2],arr[i][3]));
                            break;
                        }
                    }
                }
            }
        }
    }

判断输入的金额和原因是否合法

定义四个方法,首先是boolean isNumberic正则式判断是否全为数字,用pattern和matcher类实现,其次是 int printInt将字符串数字转换为数字类型Integer.parseInt(x),返回数值,然后是正则式判断是否全为汉字 boolean isChinese,最后是printString。

//判断字符串是否全是数字
    public static boolean isNumberic(String str){
        //使用正则式判断是否全为数字
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }
    //将字符串转换为int类型,返回数值
    public static int printInt(String x){
        if(isNumberic(x)){//是否全是数字
            //将数字字符串转为int型数字
            int y = Integer.parseInt(x);
            return y;
        }else{
            while(true){//死循环,直到输入正确为止
                System.out.println("输入出错,请重新输入:");
                String num=sc.next();
                if(isNumberic(num)){
                    int y1 = Integer.parseInt(num);
                    return y1;
                }
            }
        }
    }
    //判断是否全是汉字,是返回true,不是返回false
    public static boolean isChinese(String str){
        //正则表达式判断是否全为汉字
        Pattern p_str = Pattern.compile("[\\u4e00-\\u9fa5]+");
        Matcher m =p_str.matcher(str);//matcher类提供分组支持
        if(m.find()&&m.group(0).equals(str)){//find任意位置字符串匹配,group返回字符串索引匹配的字符串
            return true;
        }
        return false;
    }
    //判断是否全是汉字,是就返回,否则重新输入字符串
    public static String printString(String x){
        if(isChinese(x)){
            return x;
        }else{
            while(true){
                System.out.print("输入错误!请重新输入:");
                String t =sc.next();
                if(isChinese(t)){
                    return t;
                }
            }
        }
    }

收入和支出

注意,每次登记收入和支出都要记录count+1。
将int型的数据转为String类型。

public static void addRecord(String[][] arr){
        System.out.println("收入的金额:");
        String num1=sc.next();
        int money=printInt(num1);//调用判断是否全是数字
        System.out.println("收入的原因:");
        String b1=sc.next();
        String because=printString(b1);//调用判断是否全是汉字
        //标记记录为收入
        arr[count][0]="收入";
        sumMoney+=money;//计算总金额
        //将int型总金额和收入金额转为String型
        String t1=String.valueOf(sumMoney);
        String t2=String.valueOf(money);
        arr[count][1]=t1;
        arr[count][2]=t2;
        arr[count][3]=because;
        count++;//总的收支记录加一
        System.out.println("添加成功!");
    }
    //登记支出,同样不用返回
    public  static  void reduceRecord(String[][] arr){
        System.out.println("支出的金额:");
        String num2=sc.next();
        int money1=printInt(num2);
        System.out.println("支出的原因");
        String b2=sc.next();
        String because1=printString(b2);
        arr[count][0]="支出";
        sumMoney-=money1;//总金额减去这次支出的金额
        String t3=sumMoney+"";//强制转换
        String t4=money1+"";
        arr[count][1]=t3;
        arr[count][2]=t4;
        arr[count][3]=because1;
        count++;
        System.out.println("添加成功!");
    }

退出系统

判断确定退出的输入确认,y或者Y,对照的ascii码。

 public static boolean quitSystem(){
        System.out.println("确定退出?输入[Y/N]确认:");
        String t=sc.next();
        char tc=t.charAt(0);
        int tc1=(int)tc;//强制转换ASC码y的ASCII码121,Y的ASCII码89
        if((tc1==121 && t.length()==1) || (tc1==89 && t.length()==1)){
            System.out.println("\n退出成功!");
            return true;
        }else {
            System.out.println("\n已取消退出!");
            return false;
        }
    }

数组扩容

在系统运行中发现,二维数组的长度是有限,那么为了解决这个问题,可以用数组扩容,将原本数组的数据赋值到新的数组中。

//二维数组扩容,参数为二维数组
    public static String[][] expandArray(String[][] arr){
        String[][] arr1=new String[arr.length+10][4];
       if(arr[arr.length-1][0] != null){
            for(int i=0;i<arr.length;i++){
                for(int j=0;j<arr[0].length;j++){//注意二维数组的行数
                    arr1[i][j] = arr[i][j];
                }
            }
            return arr1;
        }else{
            return arr;
        }
    }

在程序运行中,遇到了问题,使用debug查看,注意二维数组的遍历,因为这里是10行4列,行数和列数并不相等,列数变量j的遍历就要是arr[0].length,表示第0行的列数。

 //扩容
            String[][] arr1 = expandArray(arr);//创建一个新的数组进行接收
            arr = arr1;//进行数组替换

注意,在数组扩容方法调用时,需要创建一个新的数组去接收,然后进行数组替换,如果直接调用expandArray(arr),新创建的数组没有被接收,会出现报错。

总结

二维数组的使用,在遍历当中需要注意行数和列数,在记账程序中,会受到数组长度的限制,无法存储更多的记录,就可以用数组扩容的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值