鱼C论坛

 找回密码
 立即注册
查看: 2807|回复: 11

[已解决]c语言做管理系统怎么输出html文件

[复制链接]
发表于 2017-7-13 11:36:46 | 显示全部楼层
本帖最后由 ba21 于 2017-7-13 11:58 编辑

2017-07-13_113515.png

  1. /*
  2. 西南石油大学计算机科学学院
  3. 课程:程序设计综合实践
  4. 教师:周永  梁宗文
  5. 编程者:张悦颖  张若曦
  6. 编程日期:2017.7.8
  7. 程序功能:商品信息管理系统*/

  8. #include<stdio.h>
  9. #include<stdlib.h>
  10. #include<conio.h>
  11. #include<string.h>
  12. #include<windows.h>

  13. #define LEN sizeof(struct commdity)
  14. #define FORMAT "%-8d%-15s%-12.1lf%-12.1lf%-12.1lf\n"
  15. #define DATA comm[i].num,comm[i].name,comm[i].price,comm[i].count,comm[i].total

  16. //定义商品信息结构体
  17. struct commdity
  18. {
  19.     int num;/*编号*/
  20.     char name[15];/*商品名称*/
  21.     double price;/*单价*/
  22.     double count;/*数量*/
  23.     double total;/*总金额*/
  24. };

  25. struct commdity comm[50];/*定义结构体数组*/

  26. void in();/*录入商品信息*/
  27. void show();/*显示商品信息*/
  28. void order();/*按总金额排序*/
  29. void del();/*删除商品信息*/
  30. void modify();/*修改商品息*/
  31. void menu();/*主菜单*/
  32. void insert();/*插入商品信息*/
  33. void total();/*计算总商品数*/
  34. void search();/*查找商品信息*/
  35. void printLogo();
  36. void exportToHtmlFile();



  37. //主函数
  38. void main()
  39. {
  40.     int n;
  41.     printLogo();
  42.     menu();
  43.     scanf("%d",&n);
  44.         //输入选择功能的编号
  45.     while(n)
  46.     {
  47.         switch(n)
  48.         {
  49.         case 1:
  50.             in();    /*调用录入商品信息过程*/
  51.             break;
  52.         case 2:
  53.             search();   /*查找商品信息过程*/
  54.             break;
  55.         case 3:
  56.             del();     /*调用删除商品信息的过程*/
  57.             break;
  58.         case 4:
  59.             modify();   /*调用修改商品信息的过程*/
  60.             break;
  61.         case 5:
  62.             insert();   /*调用插入数据的过程*/
  63.             break;
  64.         case 6:
  65.             order();   /*调用排序过程*/
  66.             break;
  67.         case 7:
  68.             total();   /*计算总数*/
  69.             break;
  70.         case 8:           
  71.             exportToHtmlFile();
  72.             break;

  73.         default:break;
  74.         }
  75.         getch();
  76.         menu();  
  77.                 //执行完功能再次显示菜单界面
  78.         scanf("%d",&n);
  79.     }

  80. }



  81. //录入商品信息
  82. void in()
  83. {
  84.     int i,m=0;/*m是记录的条数*/
  85.     char ch[2];
  86.     FILE *fp;
  87.         //定义文件指针
  88.     if((fp=fopen("data","ab+"))==NULL)
  89.                 //打开指定文件
  90.     {
  91.         printf("不能打开文件!\n");
  92.         return;
  93.     }
  94.     while(!feof(fp))
  95.     {
  96.         if(fread(&comm[m] ,LEN,1,fp)==1)
  97.             m++;
  98.                 //统计当前记录条数
  99.     }
  100.     fclose(fp);
  101.     if(m==0)
  102.         printf("没有找到!\n");
  103.     else
  104.     {
  105.         system("cls");
  106.         show();/*调用show函数,显示原有信息*/
  107.     }
  108.     if((fp=fopen("data","wb"))==NULL)
  109.     {
  110.         printf("不能打开文件!\n");
  111.         return;
  112.     }
  113.     for(i=0;i<m;i++)
  114.         fwrite(&comm[i] ,LEN,1,fp);
  115.         //向指定的磁盘文件写入信息
  116.     printf("是否输入?(y/n):");
  117.     scanf("%s",ch);
  118.     while(strcmp(ch,"Y")==0||strcmp(ch,"y")==0)
  119.     //判断是否要录入新信息
  120.     {
  121.         printf("编号:");
  122.         scanf("%d",&comm[m].num);/*输入学生学号*/
  123.         for(i=0;i<m;i++)
  124.             if(comm[i].num == comm[m].num)
  125.             {
  126.                 printf("该记录已经存在,按任意键继续!");
  127.                 getch();
  128.                 fclose(fp);
  129.                 return;
  130.             }
  131.             printf("商品名:");
  132.             scanf("%s",comm[m].name);   /*输入学生姓名*/
  133.             printf("单价:");
  134.             scanf("%lf",&comm[m].price);   /*输入商品单价*/
  135.             printf("数量:");
  136.             scanf("%lf",&comm[m].count);   /*输入商品数量*/
  137.             comm[m].total=comm[m].price * comm[m].count;  /*计算出总金额*/
  138.             if(fwrite(&comm[m],LEN,1,fp)!=1)  
  139.                         //将新录入的信息写入指定的磁盘文件
  140.             {
  141.                 printf("不能保存!");
  142.                 getch();
  143.             }
  144.             else
  145.             {
  146.                 printf("%s 已经保存!\n",comm[m].name);
  147.                 m++;
  148.             }
  149.             printf("是否继续?(y/n):");
  150.                         //是否继续
  151.             scanf("%s",ch);
  152.     }
  153.     fclose(fp);
  154.     printf("OK!\n");
  155. }





  156. //显示商品信息
  157. void show()     
  158. {
  159.     FILE *fp;
  160.     int i,m=0;
  161.     fp=fopen("data","ab+");
  162.     while(!feof(fp))
  163.     {
  164.         if(fread(&comm[m] ,LEN,1,fp)==1)
  165.             m++;
  166.     }  
  167.     fclose(fp);
  168.     printf("编号     商品名称      单价       数量      总金额\t\n");
  169.     for(i=0;i<m;i++)
  170.     {
  171.         printf(FORMAT,DATA);
  172.                 //将信息按指定格式打印
  173.     }
  174. }




  175. //自定义函数实现菜单功能
  176. void menu()           
  177. {
  178.     system("cls");
  179.     printf("\n\n\n\n\n");
  180.     printf("\t\t|-------------------商品管理系统-----------------|\n");
  181.     printf("\t\t|\t 0. 退出                                 |\n");
  182.     printf("\t\t|\t 1. 录入记录                             |\n");
  183.     printf("\t\t|\t 2. 查找记录                             |\n");
  184.     printf("\t\t|\t 3. 删除记录                             |\n");
  185.     printf("\t\t|\t 4. 修改记录                             |\n");
  186.     printf("\t\t|\t 5. 插入记录                             |\n");
  187.     printf("\t\t|\t 6. 排序记录                             |\n");
  188.     printf("\t\t|\t 7. 统计记录                             |\n");
  189.     printf("\t\t|\t 8. 网页保存数据                            |\n");

  190.     printf("\t\t|------------------------------------------------|\n\n");
  191.     printf("\t\t\t选择(0-8):");
  192. }





  193. //自定义排序函数
  194. void order()   
  195. {
  196.     FILE *fp;
  197.     struct commdity t;
  198.     int i=0,j=0,m=0;
  199.     if((fp=fopen("data","ab+"))==NULL)
  200.     {
  201.         printf("不能打开文件!\n");
  202.         return;
  203.     }
  204.     while(!feof(fp))
  205.         if(fread(&comm[m] ,LEN,1,fp)==1)
  206.             m++;
  207.         fclose(fp);
  208.         if(m==0)
  209.         {
  210.             printf("没有记录!\n");
  211.             return;
  212.         }
  213.         for(i=0;i<m-1;i++)
  214.             for(j=i+1;j<m;j++)   /*双重循环实现总金额比较并交换*/
  215.                 if(comm[i].total < comm[j].total)
  216.                 {
  217.                     t=comm[i];
  218.                     comm[i]=comm[j];
  219.                     comm[j]=t;
  220.                 }
  221.                 if((fp=fopen("data","wb"))==NULL)
  222.                 {
  223.                     printf("不能打开\n");
  224.                     return;
  225.                 }
  226.                 for(i=0;i<m;i++)/*将重新排好序的内容重新写入指定的磁盘文件中*/
  227.                     if(fwrite(&comm[i] ,LEN,1,fp)!=1)
  228.                     {
  229.                         printf("%s 不能保存!\n");
  230.                         getch();
  231.                     }
  232.                     fclose(fp);
  233.                     printf("保存成功\n");
  234. }



  235. //自定义删除函数
  236. void del()
  237. {
  238.     FILE *fp;
  239.     int snum,i,j,m=0;
  240.     char ch[2];
  241.     if((fp=fopen("data","ab+"))==NULL)
  242.     {
  243.         printf("不能打开文件\n");
  244.         return;
  245.     }
  246.     while(!feof(fp))  
  247.         if(fread(&comm[m],LEN,1,fp)==1)
  248.             m++;
  249.         fclose(fp);
  250.         if(m==0)
  251.         {
  252.             printf("没有记录!\n");
  253.             return;
  254.         }
  255.         printf("请输入编号:");
  256.         scanf("%d",&snum);
  257.         for(i=0;i<m;i++)
  258.             if(snum==comm[i].num)
  259.                 break;
  260.             if(i==m)
  261.             {
  262.                 printf("没有找到!");
  263.                 getchar();
  264.                 return;
  265.             }
  266.             printf("已经找到该记录,是否删除?(y/n)");
  267.             scanf("%s",ch);
  268.             if(strcmp(ch,"Y")==0||strcmp(ch,"y")==0)/*判断是否要进行删除*/
  269.             {
  270.                 for(j=i;j<m;j++)
  271.                     comm[j] = comm[j+1];/*将后一个记录移到前一个记录的位置*/
  272.                 m--;/*记录的总个数减1*/
  273.                 printf("成功删除!\n");
  274.             }
  275.             if((fp=fopen("data","wb"))==NULL)
  276.             {
  277.                 printf("不能打开!\n");
  278.                 return;
  279.             }
  280.             for(j=0;j<m;j++)/*将更改后的记录重新写入指定的磁盘文件中*/
  281.                 if(fwrite(&comm[j] ,LEN,1,fp)!=1)
  282.                 {
  283.                     printf("不能保存!\n");
  284.                     getch();
  285.                 }
  286.                 fclose(fp);
  287.                
  288. }






  289. //自定义查找函数
  290. void search()
  291. {
  292.     FILE *fp;
  293.     int snum,i,m=0;
  294.     char ch[2];
  295.     if((fp=fopen("data","ab+"))==NULL)
  296.     {
  297.         printf("不能打开文件\n");
  298.         return;
  299.     }
  300.     while(!feof(fp))
  301.         if(fread(&comm[m],LEN,1,fp)==1)
  302.             m++;
  303.         fclose(fp);
  304.         if(m==0)
  305.         {
  306.             printf("没有记录!\n");
  307.             return;
  308.         }
  309.         printf("请输入编号:");
  310.         scanf("%d",&snum);
  311.         for(i=0;i<m;i++)
  312.             if(snum == comm[i].num)
  313.                         //查找输入的编号是否在记录中
  314.             {
  315.                 printf("已经找到该记录,是否显示?(y/n)");
  316.                 scanf("%s",ch);
  317.                 if(strcmp(ch,"Y")==0||strcmp(ch,"y")==0)
  318.                 {
  319.                     printf("编号     商品名称      单价       数量      总金额 \t\n");
  320.                     printf(FORMAT,DATA);
  321.                                         //将查找出的结果按指定格式输出
  322.                     break;
  323.                 }
  324.                 else
  325.                     return;
  326.             }   
  327.             if(i==m)
  328.                 printf("没有找到相应的记录!\n");/*未找到要查找的信息*/
  329. }






  330. //自定义修改函数
  331. void modify()
  332. {
  333.     FILE *fp;
  334.     int i,j,m=0,snum;
  335.         char ch[2];

  336.     if((fp=fopen("data","ab+"))==NULL)
  337.     {
  338.         printf("不能打开文件!\n");
  339.         return;
  340.     }
  341.     while(!feof(fp))  
  342.         if(fread(&comm[m],LEN,1,fp)==1)
  343.             m++;
  344.         if(m==0)
  345.         {
  346.             printf("没有记录!\n");
  347.             fclose(fp);
  348.             return;
  349.         }
  350.         printf("请输入要修改的记录信息的编号!\n");
  351.         scanf("%d",&snum);
  352.         for(i=0;i<m;i++)
  353.             if(snum==comm[i].num)
  354.                         //检索记录中是否有要修改的信息
  355.                 break;
  356.             if(i<m)
  357.             {        
  358.                 printf("已经找到该记录,是否修改?(y/n)\n");
  359.                 scanf("%s",ch);
  360.                 if(strcmp(ch,"Y")==0||strcmp(ch,"y")==0)
  361.                     
  362.                 {
  363.                     printf("商品名:\n");
  364.                     scanf("%s",comm[i].name);/*输入名字*/
  365.                     printf("\n单价:");
  366.                     scanf("%lf",&comm[i].price);/*输入商品单价*/
  367.                     printf("\n数量:");
  368.                     scanf("%lf",&comm[i].count);/*输入商品数量*/
  369.                     comm[i].total = comm[i].price  * comm[i].count;
  370.                     printf("保存成功!");
  371.                 }
  372.                 else
  373.                     return;
  374.                
  375.             }
  376.             else
  377.             {
  378.                 printf("没有找到!");
  379.                 getchar();
  380.                 return;
  381.             }
  382.             if((fp=fopen("data","wb"))==NULL)
  383.             {
  384.                 printf("不能打开文件!\n");
  385.                 return;
  386.             }
  387.             for(j=0;j<m;j++)
  388.                 if(fwrite(&comm[j] ,LEN,1,fp)!=1)
  389.                 {
  390.                     printf("不能保存!");
  391.                     getch();
  392.                 }
  393.                             //将新修改的信息写入指定的磁盘文件中
  394.                 fclose(fp);
  395. }





  396. //自定义插入函数
  397. void insert()
  398. {
  399.         FILE *fp;
  400.         int i,j,k,m=0,snum;
  401.         if((fp=fopen("data","ab+"))==NULL)
  402.         {
  403.                 printf("不能打开文件!\n");
  404.                 return;
  405.         }
  406.         while(!feof(fp))  
  407.                 if(fread(&comm[m],LEN,1,fp)==1)
  408.                         m++;
  409.                 if(m==0)
  410.                 {
  411.                         printf("没有记录!\n");
  412.                         fclose(fp);
  413.                         return;
  414.                 }
  415.                 printf("请输入要插入的位置\n");
  416.                 scanf("%d",&snum);/*输入要插入的位置*/
  417.                 for(i=0;i<m;i++)
  418.                         if(snum == comm[i].num)
  419.                                 break;
  420.                         for(j=m-1;j>i;j--)
  421.                                 comm[j+1] = comm[j];
  422.                         //从最后一条记录开始均向后移一位
  423.                         printf("现在输入新的信息.\n");
  424.                         printf("编号:");
  425.                         scanf("%d",&comm[i+1].num);
  426.                         for(k=0;k<m;k++)
  427.                                 if(comm[k].num==comm[i+1].num && k!=i+1)
  428.                                 {
  429.                                         printf("已经存在该编号,按任意键继续!");
  430.                                         getch();
  431.                                         fclose(fp);
  432.                                         return;
  433.                                 }
  434.                         
  435.                                 printf("商品名:");
  436.                                 scanf("%s",comm[i+1].name);
  437.                                 printf("单价:");
  438.                                 scanf("%lf",&comm[i+1].price);
  439.                                 printf("数量:");
  440.                                 scanf("%lf",&comm[i+1].count);
  441.                             comm[i+1].total = comm[i+1].price * comm[i+1].count;
  442.                                 if((fp=fopen("data","wb"))==NULL)
  443.                                 {
  444.                                         printf("不能打开文件\n");
  445.                                         return;
  446.                                 }
  447.                                 for(k=0;k<=m;k++)
  448.                                         if(fwrite(&comm[k] ,LEN,1,fp)!=1)/*将修改后的记录写入磁盘文件中*/
  449.                                         {
  450.                                                 printf("不能保存!");
  451.                                                 getch();
  452.                                         }
  453.                                         fclose(fp);
  454. }









  455. //统计
  456. void total()
  457. {
  458.     FILE *fp;
  459.     int m=0;
  460.     if((fp=fopen("data","ab+"))==NULL)
  461.     {         
  462.         printf("不能打开记录!\n");
  463.         return;
  464.     }
  465.     while(!feof(fp))  
  466.         if(fread(&comm[m],LEN,1,fp)==1)
  467.             m++;/*统计记录个数即记录个数*/
  468.         if(m==0)
  469.         {
  470.             printf("没有记录!\n");
  471.             fclose(fp);
  472.             return;
  473.         }
  474.         printf("一共有 %d 条记录!\n",m);/*将统计的个数输出*/
  475.         fclose(fp);
  476. }




  477. //打印网页

  478. void exportToHtmlFile()
  479. {
  480.                 FILE *fh;
  481.                 FILE *fp;
  482.         int  iCounter=0,i;  //建议最好内存中,有一个变量,一直维护二进制文件中的记录数。免得每次统计。

  483.                 //读取数据
  484.                 fp=fopen("data","ab+"); //打开数据文件
  485.                 while(!feof(fp))
  486.                 {
  487.                  if(fread(&comm[iCounter] ,LEN,1,fp)==1)
  488.             iCounter++;
  489.                 }  
  490.                 fclose(fp);//关闭数据文件
  491.                 if(iCounter == 0)
  492.                 {
  493.                         printf("还没有可以导出的数据!");
  494.                          return;
  495.                 }

  496.         fh=fopen("export.html", "w");  //以写的方式打开html文件       
  497.         if (fh==NULL)
  498.         {
  499.                 printf("导出文件失败。请将当前可执行程序拷贝到具有写权限的磁盘位置。\n");
  500.                 return;
  501.         }

  502.         //第一步,写入网页的开头部分
  503.         fprintf(fh,"<!--版权所有  201631064204张若曦        201631064206张悦颖 -->\n");
  504.         fprintf(fh,"<html>\n");
  505.         fprintf(fh,"<head><title>商品信息管理</title></head>\n"); //浏览器标题栏显示的文字
  506.         fprintf(fh,"<body>\n");
  507.         fprintf(fh,"<center><h2>商品信息管理</h2><hr></center>\n"); //网页正文中的标题文字
  508.         fprintf(fh,"<div align=center>\n");
  509.         fprintf(fh,"<table border=1 width=80%%>\n");  //特备注意:网页代码中的%,在fprintf的双引号之内,要变成%%

  510.         //第二步,写入表格的表头部分。要写入的信息,在双引号中。
  511.         fprintf(fh,"<tr>\n");
  512.         fprintf(fh,"\t<td width=25%%><b>编号</b></td>\n");
  513.         fprintf(fh,"\t<td width=30%%><b>名称</b></td>\n");
  514.         fprintf(fh,"\t<td width=15%%><b>单价</b></td>\n");
  515.         fprintf(fh,"\t<td width=15%%><b>数量</b></td>\n");
  516.         fprintf(fh,"\t<td width=15%%><b>总金额</b></td>\n");
  517.         fprintf(fh,"</tr>\n");

  518.         //第三步,通过循环,写入表格的数据部分。
  519.         for(i=0;i<iCounter;i++)
  520.         {
  521.         fprintf(fh,"<tr>\n");
  522.         fprintf(fh,"\t<td width=25%%>%-8d</td>\n", comm[i].num);
  523.         fprintf(fh,"\t<td width=30%%>%-15s</td>\n", comm[i].name);
  524.         fprintf(fh,"\t<td width=15%%>%-12.1lf</td>\n", comm[i].price);
  525.         fprintf(fh,"\t<td width=15%%>%-12.1lf</td>\n", comm[i].count);
  526.         fprintf(fh,"\t<td width=15%%>%-12.1lf</td>\n", comm[i].total);
  527.         fprintf(fh,"</tr>\n");
  528.         }


  529.         //第四步,写入网页的结束部分。
  530.         fprintf(fh,"</table>\n");
  531.         fprintf(fh,"</div>\n");
  532.         fprintf(fh," <center><h5>201631064204张若曦        201631064206张悦颖 于201707《程序设计综合实践》实现的网页导出功能</h5><center>\n");
  533.         fprintf(fh,"</body></html>\n");
  534.         //关闭文件
  535.         fclose(fh);

  536.         //打印成功消息
  537.         printf("成功导出%d数据到当前目录下的export.html文件中\n",  iCounter);
  538.         printf("\a");  //用蜂鸣声提醒
  539. }







  540. //编程者
  541. void printLogo()
  542. {
  543.         system("color FB");  
  544.         printf("            . ☆∵ ∴∵ ∴∵∴ ∵╭ ∵╭ ∴╭ ☆╭ ∴ ★∵∴\n");
  545.         printf("          . . ∵ ∴★. ∴∵∴ ╭ ╯ ╭ ╯ ╭ ╯ ╭ ╯ ∴∵∴∵∴\n");
  546.         printf("         . ☆. ☆∴∵. ∴∵∴▍▍ ▍▍ ▍▍ ▍▍ ☆ ★∵∴\n");
  547.         printf("              ▍. ∴∵∴∵. ∴▄███████████☆ ★ ∵\n");
  548.         printf("               ◥█▆▆▆▆███▆█▆█▆█▆█▆█▆███◤\n");
  549.         printf("                 ◥████████☆ C  P  P ☆█████◤\n");
  550.         printf("             .. .. ◥█████████████████◤\n");
  551.         printf("\n");
  552.         printf("         ╭───────────────────────────────╮\n");
  553.         printf("         │ ╔═╦═╗╔═╦═╗╔═╦═╗╔═╦═╗╔═╦═╗╔═╦═╗  │\n");
  554.         printf("         │ ║      ║║      ║║      ║║      ║║  ║  ║║      ║  │\n");
  555.         printf("         │ ╠  商  ╣╠  品  ╣╠  管  ╣╠  理  ╣╠  系  ╣╠  统  ╣  │\n");
  556.         printf("         │ ║      ║║      ║║      ║║      ║║      ║║      ║  │\n");
  557.         printf("         │ ╚═╩═╝╚═╩═╝╚═╩═╝╚═╩═╝╚═╩═╝╚═╩═╝  │\n");
  558.         printf("         └───-◎◎─────────────◎◎───────────┘\n");
  559.         printf("\n");
  560.         printf("               ████████████████████████       \n");
  561.         printf("              *                                                *      \n");
  562.         printf("             *   ┏╮╱╱     作者:                             *     \n");
  563.         printf("            *    ╰★╮                                          *    \n");
  564.         printf("           *   ╱╱╰┛          张若曦                           *   \n");
  565.         printf("          *                                                        *  \n");
  566.         printf("         *                       张悦颖                             * \n");
  567.         printf("         *                                                          * \n");
  568.         printf("         *                        西南石油大学                      * \n");
  569.         printf("         *                                                          * \n");
  570.         printf("         *                          计算机科学学院                  * \n");
  571.         printf("          *                                                        *  \n");
  572.         printf("           *                            物联网工程                *   \n");
  573.         printf("            *                                                    *    \n");
  574.         printf("             *              ☆╭~~~╮(o^.^o)☆                  *     \n");
  575.         printf("              *                                                *      \n");
  576.         printf("               ████████████████████████       \n");
  577.         Sleep(3000);
  578.         system("cls");
  579. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-7-13 20:01:33 | 显示全部楼层

主要是C币
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 20:02:35 | 显示全部楼层

什么我不是最佳。。人家几行字说写文件,我连代码都给你搞上去了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-13 20:55:00 | 显示全部楼层


我也不知道

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +2 收起 理由
無聊 + 5 + 5 + 2 替楼主给C币, 虽然少了点

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-10-27 03:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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