目录
1、‘用C#编写一个员工工资计算’问题描述
2、个人思考和实现
2.1代码实现:
2.2调试结果及保存txt内容:
3、他人的实现
3.1代码实现:
3.2保存的txt内容:
1、‘用C#编写一个员工工资计算’问题描述
请用C#编写一个工资计算Console App:需要读取一个.txt文件里的员工信息然后计算出相关实付工资(扣除个人所得税和养老金)。这是根据国外一个公司的需要,员工是年薪制,但是工资是按每两周发放一次。
1.txt文件里的员工信息如下:
| 员工编号 | 员工姓 | 员工名 | 年薪 | 扣除养老金比例 |
3 , Zhang , San , 60000 , 4%
4 , Li , Si ,45000 , 0%
5 , Wang , Fei , 55000 , 3%
(个人所得税比例:年收入48000 以内:17.5%;年收入48000至70000: 30%;年收入70000以上:33%)
2.要求:读取.txt文字信息,然后在屏幕显示计算结果
(1)计算出员工时薪 (公式:年薪 / 52周每年 / 40小时每周 ) :
(2)实付工资(公式:工资 - 养老金 - 税):
3.要求:程序需要有的几个功能:
1.能根据员工 ID 显示所有员工实付工资
2.保存计算后的每两周实付工资信息为.txt格式文件
3.输入员工 ID 能查找员工个人信息和工资信息
4.运行程序时屏幕显示如下操作选项供用户选择:
(1)计算每两周工资
(2) 显示员工信息
(3)输入一个员工编号能查找员工信息
(4)保存信息到.txt文档
(5) 退出
5.要求每次用户选择以上一个功能时显示结果,并再次显示操作选项让客户选择,只有客户退出功能程序才会关闭。
2、个人思考和实现
针对上面的问题,我自己考虑实现一下该app。这里我主要来考虑的点是:读取txt文件,保存txt文件,txt内容解析数组存放,然后就是通过序号作为主键对各个数组关联,再就是各自的计算显示啦。如此,我进行了以下的实现。
原始txt数据内容:
2.1代码实现:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Text.RegularExpressions; namespace EmployeeSalary_calc { class EmployeeSalary { private int[] ID; private string[] name; private double[] salary; private double[] pensionRatio; private double[] hourSalary; private double[] realMoney; private double[] twoweekSalary; private int Count; public List<string> readTxt(string filePath) { int count = 0; List<String> list = new List<string>(); StreamReader sR = File.OpenText(filePath); string nextLine; while ((nextLine = sR.ReadLine()) != null) { Console.WriteLine(nextLine); if(count > 0)//第一行表头不解析 { list.Add(nextLine); } count++; } Count = count-1; sR.Close(); return list; } public void initAndgetInfo(List<String>list) { ID = new int[Count]; name = new string[Count]; salary = new double[Count]; pensionRatio = new double[Count]; hourSalary = new double[Count]; realMoney = new double[Count]; twoweekSalary = new double[Count]; string[] information = list.ToArray(); int size = information.Length; for (int i = 0; i < size; i++) { string[] info = Regex.Split(information[i], @",", RegexOptions.IgnoreCase);//正则分割 int len = info.Length; if (len < 5) { Console.WriteLine("Warning:" + info + "数据信息不全"); return; } else if (len > 5) { Console.WriteLine("Warning:" + info + "数据信息过多"); return; } else { ID[i] = int.Parse(info[0]); name[i] = info[1] + info[2]; salary[i] = double.Parse(info[3]); pensionRatio[i] = int.Parse(info[4].Substring(0, info[4].IndexOf("%"))) / 100.0; hourSalary[i] = salary[i] / 52 / 40.0; if (salary[i] <= 48000) { realMoney[i] = salary[i] * (1 - pensionRatio[i] - 0.175); } else if (salary[i] > 48000 && salary[i] <= 70000) { realMoney[i] = salary[i] * (1 - pensionRatio[i]) - 48000 * 0.175 - (salary[i] - 48000) * 0.3; } else if (salary[i] > 70000) { realMoney[i] = salary[i] * (1 - pensionRatio[i]) - 48000 * 0.175 - (70000 - 48000) * 0.3 - (salary[i] - 70000) * 0.33; } else { } } Console.WriteLine(information[i] + ",时薪:" + hourSalary[i] + ",实付工资:" + realMoney[i]); } calcTwoWeekSalary(); } //显示所有员工实付工资 public void showAllRealMoneyByID() { for (int i = 0; i < Count; i++) { Console.WriteLine(ID[i] + ":实付工资" + realMoney[i]); } } //输入员工 ID 能查找员工个人信息和工资信息 public void searchInfoByID(int id) { for (int i = 0; i < ID.Length; i++) { if (id == ID[i]) { Console.WriteLine("个人信息:"+ID[i]+","+name[i]); Console.WriteLine("工资信息:年薪:" + salary[i] + ",时薪:" + hourSalary[i] + ",实付工资:" + realMoney[i]); break; } } } //显示员工个人信息和工资信息 public void showAllinfo() { for (int i = 0; i < Count; i++) { Console.WriteLine("个人信息:" + ID[i] + "," + name[i]); Console.WriteLine("工资信息:年薪:" + salary[i] + ",时薪:" + hourSalary[i] + ",实付工资:" + realMoney[i] + ",两周实付工资:" + twoweekSalary[i]); } } //计算每两周工资 public void calcTwoWeekSalary() { for (int i = 0; i < Count; i++) { twoweekSalary[i] = hourSalary[i] * 40 * 2; } } //保存计算的每两周工资为txt public void saveTwoWeekSalary(String filePath) { calcTwoWeekSalary(); FileInfo myFile = new FileInfo(filePath); StreamWriter sW = myFile.CreateText(); string[] str = new String[Count]; for (int i = 0; i < Count; i++) { str[i] = ID[i] + "," + name[i]+","+twoweekSalary[i]; } foreach (var s in str) { sW.WriteLine(s); } Console.WriteLine("保存完成!"); sW.Close(); } } class Program { static void Main(string[] args) { string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; string filepath = path + "EmployeeInformation.txt"; Console.WriteLine("txt文件存放位置:"+filepath); //这里的path可以直接写成绝对路径 EmployeeSalary Employeeinfo = new EmployeeSalary(); List<String> info = Employeeinfo.readTxt(filepath); Employeeinfo.initAndgetInfo(info); string savepath = path+"savefile.txt"; Console.WriteLine("txt文件保存位置:" + savepath); bool control = true; while (control) { Console.WriteLine("-------------------请输入以下选项代表的数字----------------------------"); Console.WriteLine("(1) 计算每两周工资"); Console.WriteLine("(2) 显示员工信息"); Console.WriteLine("(3) 输入一个员工编号能查找员工信息"); Console.WriteLine("(4) 保存信息到.txt文档"); Console.WriteLine("(5) 退出"); int flag = int.Parse(Console.ReadLine()); switch (flag) { case 1: Employeeinfo.calcTwoWeekSalary(); Console.WriteLine("计算完成!"); break; case 2: Employeeinfo.showAllinfo(); break; case 3: int id = int.Parse(Console.ReadLine()); Employeeinfo.searchInfoByID(id); break; case 4: Employeeinfo.saveTwoWeekSalary(savepath); break; case 5: Console.Write("退出程序了"); control = false; break; default: break; } } } } }
2.2调试结果及保存txt内容:
这个可以看出,对于问题中的相关功能均得到了实现,细枝末节处可能有些需要调整,主要需要根据问题的具体描述和理解进行操作。
大家看到这里是不是有什么意见吗?我自己也自我感觉良好,毕竟解决的问题呀。然而看了别人的代码和设计思路,不得不佩服一下。我代码中存在的不足大家也可以再评论区里说出来,大家一起讨论呀。下面就贴上别人实现的代码了。
3、他人的实现
以下是引用其他作者的内容,这部分实现的作者是真的小白啊
该作者的主要思路则是,将所有的元素作为一个结构体,然后统一存储在list内,并且通过多接口的方式实现各个功能模块。代码风格和思路结构就比我强很多。我贴上来也是为了做个比较,然后让自己和大家都可以学习学习。
3.1代码实现:
namespace ConsoleApp1 { internal class Program { static List<Staff> StaffList = new List<Staff>(); static void Main(string[] args) { ImportStaffs(); while (true) { switch (MainMenu()) { case 1: CalculateSalary(); break; case 2: DisplayStaffInformation(); break; case 3: FindStaff(); break; case 4: SaveToFile(); break; case 5: { Console.Clear(); Console.WriteLine("(5) 退出"); Console.ReadKey(); return; } default: break; } } } private static void FindStaff() { Console.Clear(); Console.WriteLine("(3) 输入一个员工编号能查找员工信息"); Console.Write("输入一个员工编号:"); if (int.TryParse(Console.ReadLine(), out var staffID)) { Console.WriteLine(StaffList.Find(s => s.ID == staffID)); } Console.ReadKey(); } private static void DisplayStaffInformation() { Console.Clear(); Console.WriteLine("(2) 显示员工信息"); foreach (var staff in StaffList) { Console.WriteLine(staff); } Console.ReadKey(); } private static void SaveToFile() { Console.Clear(); Console.WriteLine("(4) 保存信息到.txt文档"); var staffInfoFileNew = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "StaffInfoNew.txt"); if (File.Exists(staffInfoFileNew)) { File.Delete(staffInfoFileNew); } using var stream = new StreamWriter(staffInfoFileNew, true); foreach (var staff in StaffList) { stream.Write(staff); stream.Write(Environment.NewLine); } Console.WriteLine("保存成功"); Console.ReadKey(); } private static void ImportStaffs() { var staffInfoFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "StaffInfo.txt"); if (File.Exists(staffInfoFile)) { foreach (var staffLine in File.ReadAllLines(staffInfoFile).Skip(1)) { var staffInfo = staffLine.Split(','); var id = int.Parse(staffInfo[0]); var firstName = staffInfo[1]; var lastName = staffInfo[2]; var annualSalary = double.Parse(staffInfo[3].Trim('%')); var pensionRatio = double.Parse(staffInfo[4].Trim('%')) / 100; StaffList.Add(Staff.EnrollNew(id, firstName, lastName, annualSalary, pensionRatio)); } } } private static void CalculateSalary() { Console.Clear(); Console.WriteLine("(1) 计算每两周工资"); Console.WriteLine("每两周工资计算完成"); Console.ReadKey(); } private static int MainMenu() { Console.Title = "员工工资计算"; while (true) { Console.Clear(); Console.WriteLine("(1) 计算每两周工资"); Console.WriteLine("(2) 显示员工信息"); Console.WriteLine("(3) 输入一个员工编号能查找员工信息"); Console.WriteLine("(4) 保存信息到.txt文档"); Console.WriteLine("(5) 退出"); Console.WriteLine(); if (int.TryParse(Console.ReadLine(), out var functionID)) { if (functionID >= 1 && functionID <= 5) { return functionID; } } } } } }
namespace ConsoleApp1 { internal class Staff { private double PersonalIncomeTax { get { double personalIncomeTax = default; if (AnnualSalary < 48000) { personalIncomeTax = TwoWeeksSalary * 17.5 / 100; } else if (AnnualSalary >= 48000 && AnnualSalary < 70000) { personalIncomeTax = TwoWeeksSalary * 30 / 100; } else if (AnnualSalary >= 70000) { personalIncomeTax = TwoWeeksSalary * 33 / 100; } return personalIncomeTax; } } private double Pension => TwoWeeksSalary * PensionRatio; public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public double AnnualSalary { get; set; } public double HourlySalary => AnnualSalary / 52 / 40; public double PaidSalary => TwoWeeksSalary - Pension - PersonalIncomeTax; public double PensionRatio { get; set; } public double TwoWeeksSalary => HourlySalary * 40 * 2; private Staff() { } public static Staff EnrollNew(int id, string firstName, string lastName, double annualSalary, double pensionRatio) { var newStaff = new Staff { ID = id, FirstName = firstName, LastName = lastName, AnnualSalary = annualSalary, PensionRatio = pensionRatio }; return newStaff; } public override string ToString() { return $"ID: {ID}{Environment.NewLine}" + $"FirstName: {FirstName}{Environment.NewLine}" + $"LastName: {LastName}{Environment.NewLine}" + $"AnnualSalary: {AnnualSalary}{Environment.NewLine}" + $"HourlySalary: {HourlySalary}{Environment.NewLine}" + $"PaidSalary: {PaidSalary}{Environment.NewLine}" + $"PensionRatio: {PensionRatio}{Environment.NewLine}" + $"TwoWeeksSalary: {TwoWeeksSalary}{Environment.NewLine}" + $"PersonalIncomeTax: {PersonalIncomeTax}{Environment.NewLine}" + $"Pension: {Pension}{Environment.NewLine}"; } } }
3.2保存的txt内容:
最后,通过比较只能说自己代码的扩展性,结构性都比较差。自己还是太弱,大家可以在评论区中提出我代码中的不足。