LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1772|回复: 9

一个简单的工资管理系统,大家也可以自己先写写看

[复制链接]
发表于 2003-7-25 19:30:15 | 显示全部楼层 |阅读模式
我不知道结果是不是正确的 今天翻磁盘时找到的

当成是练习吧

/*
   =======================================================
   内容和要求:用菜单实现
   1、工资信息:序号、月份、姓名、基本工资、资金、房费、水电费、公积金、实发工资。将
   以上信息建立20个学生的信息链表,写入文件。
   2、显示如下信息:1、录入工资信息
   2、查询 按基本工资查询
   按实发工资查询
   3、修改 插入指定人员信息
   删除调出人员信息
   画出程序流程图,编写主函数及子函数,并分析运行结果,调试运行程序成功,撰写课程设
   计说明书。
   =======================================================
   源代码

   我的她要。。啊。。
   诸位同人。。。都是好心人啊。
   谁能忍心。。让俺。。做一辈子光棍啊。。谢谢。。各位了。。
   QQ:31504934
   alwsse@163.COM

*/

  1. #include <stdio.h>
  2. #include <string.h>

  3. struct Employer_info{
  4.     int            No;
  5.     int            month;
  6.     char    name[50];
  7.     int            base_salary;
  8.     int            money;  //资金什么写
  9.     int            house_money;    //房费什么写
  10.     int            water_money;   //
  11.     int            sum;            //公积金,这个也翻译一下 ,我没有金山词霸
  12.     int            real_salary;   
  13. };

  14. struct list_item{
  15.     struct Employer_info *data;
  16.     struct list_item*            next;
  17. };

  18. //把employer复制到到链表元素中 并返回这个元素
  19. struct list_item * add_new_listitem(struct Employer_info*employer)
  20. {
  21.     if(!employer)
  22.         return NULL;

  23.     struct list_item *p =(struct list_item *) malloc (sizeof(struct list_item ));
  24.     if(!p)
  25.         return NULL;

  26.     p->data=(struct Employer_info *)malloc(sizeof(struct Employer_info));
  27.     if(!p->data){
  28.         free(p);
  29.         return NULL;
  30.     }

  31.     memcpy(p->data,&employer,sizeof(struct Employer_info));
  32.     p->next = NULL;
  33.     return p;
  34. }


  35. //------------------------------------------------------------------------------
  36. //            文件操作
  37. //------------------------------------------------------------------------------
  38. //保存到文件
  39. //写一条记录
  40. //Employment_info  雇员信息
  41. static void write_one_rec(FILE* fp,struct Employer_info *employ)
  42. {
  43.     if(fp&&employ)
  44.         fprintf(fp,"序号=%d\t姓名="%s"\t月份=%d\t基本工资=%d\t奖金=%d\t\
  45.                 房费=%d\t水电费=%d\t公积金=%d\t实发工资=%d\n",
  46.                 employ->No,employ->name,employ->month,employ->base_salary,
  47.                 employ->money,employ->house_money,employ->water_money,
  48.                 employ->sum,employ->real_salary);
  49. }

  50. //从文件中读入一个雇员信息
  51. //返回 0 读入成功
  52. // 1 可能是因为已到文件尾  或是
  53. //-1 或是因为文件错误
  54. static int read_one_rec(FILE* fp,struct Employer_info* employ,int No)
  55. {
  56.     char strbuf[500],*pos=NULL;

  57.     if(!fp||!employ)
  58.         return -1;      

  59.     if(feof(fp))
  60.         return 1;
  61.    
  62.     do{
  63.         memset(strbuf,0,sizeof(strbuf));
  64.         fgets(strbuf,499,fp);
  65.     }while(strbuf[0]=='#');        //#号开始是注释

  66.     /*char *pos=strstr(strbuf,"序号=");
  67.       if(!pos)
  68.       return -1;*/
  69.     employ->No=No;

  70.     pos=strstr(strbuf,"姓名="");
  71.     if(!pos)
  72.         return -1;
  73.     char *pos2=strchr(pos,'"');
  74.     if(!pos2
  75.     ||pos2-pos>49)
  76.         return -1;
  77.     memset(employ->name,0,sizeof(employ->name));
  78.     memcpy(employ->name,pos,pos2-pos);

  79.     pos=strstr(strbuf,"月份=");
  80.     if(!pos)
  81.         return -1;
  82.     employ->month=atoi(pos);

  83.     pos=strstr(strbuf,"基本工资=");
  84.     if(!pos)
  85.         return -1;
  86.     employ->base_salary=atoi(pos);

  87.     pos=strstr(strbuf,"奖金=");
  88.     if(!pos)
  89.         return -1;
  90.     employ->money=atoi(pos);

  91.     pos=strstr(strbuf,"房费=");
  92.     if(!pos)
  93.         return -1;
  94.     employ->house_money=atoi(pos);

  95.     pos=strstr(strbuf,"水电费=");
  96.     if(!pos)
  97.         return -1;
  98.     employ->water_money=atoi(pos);

  99.     pos=strstr(strbuf,"公积金=");
  100.     if(!pos)
  101.         return -1;
  102.     employ->sum=atoi(pos);

  103.     pos=strstr(strbuf,"实发工资=");
  104.     if(!pos)
  105.         return -1;
  106.     employ->real_salary=atoi(pos);

  107.     return 0;
  108. }

  109. struct list_item* load_list_from_file(char*filename,int *No)
  110. {
  111.     struct Employer_info        employ;
  112.     struct list_item*        phead        =NULL ,*pnext = NULL;
  113.     FILE                *fp        = NULL;
  114.     int                        res        = 0;
  115.     int                        Seq        = 0;

  116.     if(No)
  117.         *No=0;

  118.     if(!filename)
  119.         return NULL;
  120.     fp= fopen(filename,"r");
  121.     if(!fp)
  122.         return NULL;

  123.     do{
  124.         memset(&employ,0,sizeof (struct Employer_info));
  125.         res = read_one_rec(fp,&employ,Seq++);
  126.         if(res)
  127.             break;

  128.         if(!phead){
  129.             phead = add_new_listitem(&employ);
  130.             pnext =phead;
  131.         }else{
  132.             pnext->next = add_new_listitem(&employ);
  133.             pnext = pnext->next;
  134.         }

  135.     }while(1);

  136.     if(No)
  137.         *No=Seq;
  138.     if(res == -1 ){
  139.         printf("file  format error\n");
  140.     }
  141.     return phead;
  142. }

  143. void save_list_to_file(struct list_item *item,char*filename)
  144. {
  145.     FILE *fp = NULL;

  146.     if(!filename)
  147.         return ;

  148.     fp = fopen(filename,"w");
  149.     if(!fp)
  150.         return ;

  151.     while(item){
  152.         write_one_rec(fp,item->data);
  153.         item=item->next;
  154.     }
  155.     fclose(fp);
  156. }



  157. //------------------------------------------------------------------------------
  158. //            记录操作
  159. //------------------------------------------------------------------------------
  160. //用户录入新记录或是修改记录
  161. //如果是修改记录那么No==NULL 不然不可为空
  162. //0 成功  -1失败
  163. int add_new_rec(struct Employer_info* employ,int* No)
  164. {
  165.     char answer;
  166.     if(!employ)
  167.         return -1;
  168.     memset(employ,0,sizeof(employ));

  169.     answer=1;
  170.     do{
  171.         printf("请输入姓名,名字不可为空,也不可以含引号和等号,最长49个字符:\bn");
  172.         fgets(employ->name,49,stdin);
  173.         fflush(NULL);
  174.         if((!employ->name[0])||strchr(employ->name,'"')||strchr(employ->name,'=')){
  175.             printf("输入非法,请重输\n");
  176.             answer=0;
  177.         }
  178.     }while(!answer);

  179.     printf("请输入月份、基本工资、奖金:\n");
  180.     scanf("%d%d%d",employ->month,employ->base_salary,employ->money);

  181.     printf("请输入房费、水电费、公积金、实发工资:\n");
  182.     scanf("%d%d%d%d",employ->house_money,employ->water_money,employ->sum,employ->real_salary);

  183.     printf("姓名="%s"\n月份=%d\t基本工资=%d\t奖金=%d\n\
  184.             房费=%d\t水电费=%d\t公积金=%d\t实发工资=%d\n
  185.             以上信息正确吗:如果是那么请输入y,敲其它键退回菜单\n",
  186.             employ->name,employ->month,employ->base_salary,
  187.             employ->money,employ->house_money,employ->water_money,
  188.             employ->sum,employ->real_salary);
  189.     scanf("%c",&answer);

  190.     if(answer=='y'||answer=='Y'){
  191.         printf("保存....\n");
  192.         if(No)
  193.             employ->No=++(*No);

  194.         return 0;
  195.     }

  196.     printf("信息没有保存\n");
  197.     return -1;
  198. }


  199. //查询信息
  200. //query_type  查询方式 0 基本工资,非0 实发工资
  201. //query_num   金额
  202. void query_info(struct list_item*list)
  203. {
  204.     int query_type=0, query_num=0;
  205.     struct Employer_info* employ=NULL;

  206.     if(!list){
  207.         printf("没有雇员记录\n");
  208.         return ;
  209.     }

  210.     printf("请输入查询类型(0根据基本工资  其它 根据实发工资)和查询金额:\n");   
  211.     scanf("%d%d",&query_type,&query_num);

  212.     while(list){
  213.         if(!list->data)
  214.             break ;

  215.         if(query_type==0&&query_num==list->data->base_salary)
  216.             break;
  217.         else if(query_num==list->data->real_salary)
  218.             break;

  219.         list=list->next;
  220.     }
  221.     if(!list )
  222.         return ;
  223.        
  224.         employ = list->data;
  225.     printf("序号=%d\t姓名="%s"\n月份=%d\t基本工资=%d\t奖金=%d\n\
  226.             房费=%d\t水电费=%d\t公积金=%d\t实发工资=%d\n
  227.             敲其它键退回菜单\n",
  228.             employ->No,employ->name,employ->month,employ->base_salary,
  229.             employ->money,employ->house_money,employ->water_money,
  230.             employ->sum,employ->real_salary);

  231.     getch();       
  232. }

  233. //通过名字定位记录
  234. struct Employer_info* find_rec_by_name(struct list_item*list)
  235. {
  236.     char  name[50];

  237.     if(!list){
  238.         printf("没有雇员记录\n");
  239.         return NULL;
  240.     }

  241.     do{
  242.         memset(name,0,sizeof(name));
  243.         printf("请输入要操作的雇员名:\n");
  244.         fgets(name,49,stdin);

  245.         fflush(NULL);
  246.         if((!name[0])||strchr(name,'"')||strchr(name,'=')){
  247.             printf("输入非法,请重输\n");
  248.         }
  249.         else
  250.             break;
  251.     }while(1);

  252.     while(list){
  253.         if(!list->data)
  254.             break ;

  255.         if(strcmp(list->data->name,name))
  256.             break;

  257.         list=list->next;
  258.     }

  259.     if(!list ||!list->data){
  260.         printf("没有找到对应记录\n");
  261.         return NULL;
  262.     }

  263.     return list->data;
  264. }

  265. //list                雇员信息表
  266. //oper_type        操作类型   1 添加 2查询 3修改  4删除
  267. //No                序号   
  268. void employer_oper(struct list_item **list,int oper_type,int *No)
  269. {
  270.     struct Employer_info employer,*p_employer=NULL;
  271.     struct list_item *plist=NULL;
  272.     int ret;

  273.     switch(oper_type) {
  274.         case 1:
  275.             memset(&employer,0,sizeof(struct Employer_info));
  276.             ret=add_new_rec(&employer,No);
  277.             if(ret)
  278.                 break;

  279.             if(!*list){
  280.                 *list = add_new_listitem(&employer);
  281.                 if(!*list)
  282.                     *No--;
  283.             }
  284.             else{
  285.                 plist = *list;
  286.                 while(plist->next)
  287.                     plist=plist->next;

  288.                 plist->next = add_new_listitem(&employer);
  289.                 if(!plist->next)
  290.                     *No--;
  291.             }
  292.             break;
  293.         case 2:
  294.             query_info(*list);
  295.             break;
  296.         case 3:
  297.             p_employer = find_rec_by_name(*list);
  298.             if(p_employer){
  299.                 add_new_rec(p_employer,NULL);
  300.             }
  301.             break;
  302.         case 4:
  303.             p_employer = find_rec_by_name(*list);
  304.             if(p_employer){
  305.                 plist = *list;
  306.                 while(plist->next->data!=p_employer)
  307.                     plist=plist->next;
  308.                 plist->next = plist->next->next;
  309.                 free(plist->next);
  310.                 while(plist){
  311.                     plist->data->No--;
  312.                     plist=plist->next;
  313.                 }
  314.                 *No--;
  315.             }            
  316.             break;
  317.             //        case 4:
  318.             //            break;
  319.         default:
  320.             break;
  321.     }
  322. }


  323. main(int argc,char**argv)
  324. {
  325.     struct list_item* list = NULL;
  326.     int        oper_type        =0;
  327.     int        No=0;

  328.     if(argc!=2){
  329.         printf ("参数错误:调用方法为:\n\t程序名 数据文件名\n");
  330.         exit(0);
  331.     }


  332.     list = load_list_from_file(argv[1],&No);

  333.     while(oper_type!=5){
  334.         employer_oper(&list,oper_type,No);
  335.         printf("请输入1-5选择操作:\n\
  336.                 1、录入工资信息 \n\
  337.                 2、查询 按基本工资查询 \n\
  338.                 按实发工资查询 \n\
  339.                 3、修改 插入指定人员信息 \n\
  340.                 4. 删除调出人员信息 \n\
  341.                 5. 退出\n");
  342.         scanf("%d",&oper_type);
  343.     }

  344.     save_list_to_file(list,argv[1]);
  345. }
复制代码
发表于 2003-7-25 21:58:55 | 显示全部楼层
这个程序我看到过,可以编译运行。我想用C++重新写一个,算是作练习吧。
发表于 2003-7-25 23:05:05 | 显示全部楼层
[linuxer@localhost csdn]$ gcc gonzi.c -o gonzi
gonzi.c:245:10: warning: multi-line string literals are deprecated
gonzi.c:297:10: warning: multi-line string literals are deprecated
gonzi.c: In function `main':
gonzi.c:426: warning: passing arg 3 of `employer_oper' makes pointer from integer without a cast
/tmp/ccJgMQY2.o(.text+0x8b4): In function `query_info':
: undefined reference to `getch'
collect2: ld returned 1 exit status
发表于 2003-7-25 23:08:05 | 显示全部楼层
自己改动一下。
 楼主| 发表于 2003-7-26 11:53:37 | 显示全部楼层
自己改一下
这是在windows下编译的

另外用C++也可以吧 只是那时想练习C就使用C了
发表于 2003-7-26 16:55:03 | 显示全部楼层
搞了一天,只能出来这么个自己看着也别扭的东西。代码中使用了运算符重载和自定义谓词。但是出错处理和异常处理都没有完善,一些功能也没有实现。程序的框架是完整的,维护起来也比较方便。大家如果有兴趣,可以在此基础上进一步完善。
我是在win98和dev-c++下编译的。

  1. /*
  2. 一个简单的工资管理系统
  3. 内容和要求:用菜单实现
  4. 1、工资信息:序号、月份、姓名、基本工资、资金、房费、水电费、公积金、实发工资。
  5. 将以上信息建立20个职员的信息链表,写入文件。
  6. 2、显示如下信息:
  7.     1、录入工资信息
  8.     2、查询 按基本工资查询
  9.         按实发工资查询
  10. 3、修改 插入指定人员信息
  11.     删除调出人员信息
  12. */
  13. #include<iostream>
  14. #include<list>
  15. #include<fstream>
  16. #include<functional>
  17. #include<algorithm>
  18. using namespace std;

  19. class Employee {
  20. public:
  21.     int serial_number;    //序号
  22.     int employed_month;   //工作月份
  23.     string name;          //姓名
  24.     float base_salary;    //基本工资
  25.     float award;          //奖金
  26.     float house_rent;     //房费
  27.     float charges;        //水电费
  28.     float accu_fund;      //公积金
  29.     float real_wages;     //实发工资
  30.    
  31.     Employee& operator=(const Employee& rv) {
  32.         serial_number = rv.serial_number;
  33.         employed_month = rv.employed_month;
  34.         name = rv.name;
  35.         base_salary = rv.base_salary;
  36.         award = rv.award;
  37.         house_rent = rv.house_rent;
  38.         charges = rv.charges;
  39.         accu_fund = rv.accu_fund;
  40.         real_wages = rv.real_wages;
  41.         
  42.         return *this;
  43.     }
  44.    
  45.     friend istream&
  46.     operator>>(istream& is, Employee& emp) {
  47.         is >> emp.serial_number >> emp.employed_month >> emp.name >>
  48.                 emp.base_salary >> emp.award >> emp.house_rent >>
  49.                 emp.charges >> emp.accu_fund >> emp.real_wages;
  50.         return is;
  51.     }
  52.    
  53.     friend ostream&
  54.     operator<<(ostream& os, Employee& emp) {
  55.         os << emp.serial_number << ' ' << emp.employed_month <<
  56.                 ' ' << emp.name << ' ' << emp.base_salary << ' '
  57.                 << emp.award << ' ' << emp.house_rent << ' ' <<
  58.                 emp.charges << ' ' << emp.accu_fund << ' ' << emp.real_wages;
  59.         os << endl;
  60.         return os;
  61.     }
  62. };


  63. //用户界面处理
  64. class Ui {
  65.     list<Employee> emplist;
  66. public:
  67.     Ui();
  68.     ~Ui();
  69.     void showmenu(void) const;
  70.     Employee input(void);
  71.     void query(float base_salary);
  72.     void query(float real_wages, bool);
  73.     list<Employee>::iterator query(string name);
  74.     void modify();
  75.     void erase();
  76.     void run();
  77.     void outputf(const Employee& x) const;
  78. };

  79. Ui::Ui() {
  80.     //从文件读取数据
  81.     ifstream datafile("data.txt");
  82.     if(!datafile) cout<<"error open file data.txt\n";
  83.     Employee temp;
  84.     while ( datafile >> temp )
  85.     emplist.push_back(temp);
  86.     //显示菜单
  87.     //showmenu();
  88.     datafile.close();
  89.     cout<<"load file OK!\n";
  90. }

  91. Ui::~Ui() {
  92.     //备份数据文件,这是采用的是dos命令。
  93.     system("del data.bak");     //linux下可改为"rm data.bak"
  94.     system("rename data.txt data.bak"); //linux下改为"mv data.txt data.bak"
  95.    
  96.     ofstream datafile("data.txt");
  97.     if(!datafile) cout<<"open out file error!\n";
  98.     typedef list<Employee>::iterator LI;
  99.     for(LI i = emplist.begin(); i != emplist.end(); ++i)
  100.         datafile << *i;
  101.    
  102.     cout << "exit\n";
  103. }
  104.    
  105. void Ui::showmenu(void) const {
  106.     cout << "请输入1-5选择操作:\n" <<
  107.         "1. 录入工资信息 \n" <<
  108.         "2. 查询 按基本工资查询 \n" <<
  109.         "   按实发工资查询 \n" <<
  110.         "3. 修改指定人员信息 \n" <<
  111.         "4. 删除调出人员信息 \n" <<
  112.         "5. 退出\n";
  113. }     

  114. //录入工资信息
  115. Employee Ui::input(void) {
  116.     Employee temp;
  117.     char answer;
  118.     cout << "请输入姓名,名字不可为空,也不可以含引号和等号:\n";
  119.     cin >> temp.name;
  120.     cout << "请输入月份、基本工资、奖金:\n";
  121.     cin >> temp.employed_month >> temp.base_salary >> temp.award;
  122.     cout << "请输入房费、水电费、公积金、实发工资:\n";
  123.     cin >> temp.house_rent >> temp.charges >> temp.accu_fund
  124.         >> temp.real_wages;
  125.     outputf(temp);
  126.     cout << "以上信息正确吗: (y/n)\n";
  127.     cin >> answer;
  128.     if( answer == 'y' )
  129.         return temp;
  130.     else
  131.         showmenu();
  132. }   

  133. //供query(float base_salary)和
  134. //query(float real_wages, bool)使用的自定义谓词
  135. class Eq_base : public unary_function<Employee, bool> {
  136.     float f;
  137. public:
  138.     explicit Eq_base( const float& ff):f(ff) {}
  139.     bool operator()(const Employee& x) const {
  140.         return f == x.base_salary;
  141.     }
  142. };

  143. //按基本工资查询
  144. void Ui::query(float base_salary) {
  145.     typedef list<Employee>::iterator LI;
  146.     LI p = find_if ( emplist.begin(), emplist.end(),
  147.                             Eq_base(base_salary) );
  148.     outputf(*p);
  149. }

  150. //按实发工资查询
  151. void Ui::query(float real_wages, bool) {
  152.     typedef list<Employee>::iterator LI;
  153.     LI p = find_if ( emplist.begin(), emplist.end(),
  154.                             Eq_base(real_wages) );
  155.     outputf(*p);
  156. }

  157. //供query(string name)使用的自定义谓词
  158. class Eq_name : public unary_function<Employee, bool> {
  159.     string s;
  160. public:
  161.     explicit Eq_name( const string& ss):s(ss) {}
  162.     bool operator()(const Employee& x) const {
  163.         return s == x.name;
  164.     }
  165. };

  166. //按名字查询
  167. list<Employee>::iterator Ui::query(string name) {
  168.     typedef list<Employee>::iterator LI;
  169.     LI p = find_if ( emplist.begin(), emplist.end(),
  170.                             Eq_name(name) );
  171.     return p;
  172. }

  173. //修改指定人员信息
  174. void Ui::modify() {
  175.     string name;
  176.     cout << "请输入要操作的雇员名:\n";
  177.     cin >> name;
  178.     typedef list<Employee>::iterator LI;
  179.     LI p = query(name);
  180.     *p = input();   
  181. }

  182. //删除指定人员信息
  183. void Ui::erase() {
  184.     string name;
  185.     cout << "请输入要操作的雇员名:\n";
  186.     cin >> name;
  187.     typedef list<Employee>::iterator LI;
  188.     LI p = query(name);
  189.     emplist.erase(p);
  190. }

  191. //输入界面循环及菜单处理
  192. void Ui::run() {
  193.     int i;
  194.     bool exit = false;
  195.     while(1) {
  196.         showmenu();
  197.         cin >> i;
  198.         switch(i) {
  199.                 case 1: emplist.push_back(input());
  200.                         break;
  201.                 case 2: cout<<"请输入查询类型:\n" <<
  202.                                 "0 根据基本工资\n" <<
  203.                                 "1 根据实发工资\n";
  204.                         bool t;
  205.                         cin >> t;
  206.                         cout<<"查询金额:\n";
  207.                         float num;
  208.                         cin >> num;
  209.                         if(t)
  210.                              query(num, true);
  211.                         else
  212.                              query(num);
  213.                         break;
  214.                 case 3: modify();
  215.                         break;
  216.                 case 4: erase();
  217.                         break;
  218.                 case 5: exit = true;
  219.         }
  220.         if(exit) break;
  221.     }
  222. }

  223. //为了方便而提供的格式化输出
  224. void Ui:: outputf( const Employee& temp) const {
  225.     cout << "姓名=" << temp.name << ' ' << "月份=" << temp.employed_month
  226.         << ' ' << "基本工资=" << temp.base_salary << ' ' <<
  227.         "奖金=" << temp.award << ' ' << "房费=" << temp.house_rent
  228.         << ' ' << "水电费=" << temp.charges << ' ' << "公积金=" <<
  229.         temp.accu_fund << ' ' << "实发工资=" << temp.real_wages << "\n";
  230. }

  231. int main()
  232. {
  233.     Ui x;
  234.     x.run();            
  235. }
复制代码
发表于 2003-7-26 17:19:34 | 显示全部楼层
C++的功底很高呢,佩服佩服
发表于 2003-7-26 17:22:25 | 显示全部楼层
楼上的别笑话我了,我才刚学呢。
自由狼-台风 该用户已被删除
发表于 2003-7-27 09:11:58 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2003-7-28 10:18:18 | 显示全部楼层
可以分成几个文件,如:
文件f.c:
。。。
f(){}
。。。
文件main.c:
。。。
int main()
{
  f();
}
。。。
这样在编译时用gcc main.c f.c就行了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表