C语言小工程--动态表格信息创建与文件永久性存储

功能描述
本程序旨在利用动态内存分配与文件存储的相关知识,先定义一个结构体,用于接收字段信息,包括字段名,字段类型,字段长度,字段ID。其中ID值系统自动按照顺序分配,其余属性需要用户自定义。用户需要设置字段数m和记录条数n。
比如下面这个表格:

姓名性别学号C语言成绩
张三
李四
王五

对于这个表格来说m=4,n=3。
其中姓名,性别,学号,C语言成绩都属于字段,以姓名字段为例,字段名称为“姓名”,字段类型为“s”,代表这个字段用于存储字符串,并且输入字符串长度(还有一种字段类型为“n”,用于存储数字,比如C语言成绩,若类型为n,则程序自动分配4个字节的内存)
当所有字段属性定义完毕后,打印已建立记录的字段属性信息,并进入录入信息阶段。录入信息完毕则全部打印出来,并提醒用户输入要创建的文件名,再利用fwrite()函数将整个结构体录入文件。若用户选择查询已存在的文件,则使用fread()函数读出文件的信息并打印。
具体实现细节可以参考代码中的注释:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
typedef struct FIELDATRR//定义一个结构体,用于接收字段信息,包括字段名,字段类型,字段长度,字段ID
{
     int fieldId;
     char fieldCaption[11];
     char fieldType;
     int fieldLen;

}F;
struct INFORMATION
{
    int jilu;
    int ziduan;
    int length;
}I;
int main()
{
    int m,n,i,j,sum=0;
    char ch,filename[20],findfilename[20];
    FILE *fp,*fs;
    F filde[30];
    printf("请按方括号中的字母选择功能:\n");
    printf("[C]reat a table,[L]ist a table exist,[Q]uit:");
    ch=getchar();
    if(ch=='c'||ch=='C')
   {
    printf("请输入记录的字段数:");
    scanf("%d",&m);
    I.ziduan=m;
    printf("请输入记录条数:");
    scanf("%d",&n);
    system("cls");
    for(i=0;i<m;i++)
    {
        filde[i].fieldId=i;//系统自动录入ID值
        printf("请输入字段名称:");
        scanf("%s",filde[i].fieldCaption);
        printf("请输入选择字段类型(int n,string s):");
        scanf(" %c",&filde[i].fieldType);
        if(filde[i].fieldType=='s')
        {
            printf("输入字符串长度:");
            scanf("%d",&filde[i].fieldLen);
            filde[i].fieldLen++;
            printf("一个字符属性输入完毕,按任意键继续。。。\n");
            getch();

        }
        else if(filde[i].fieldType=='n')
        {
            filde[i].fieldLen=4;
            printf("一个字符属性输入完毕,按任意键继续。。。\n");
            getch();
        }

    }
    printf("字段属性信息已录入完毕,按任意键查看。。。");
    getch();
    system("cls");
    printf("已建立记录的字段属性信息:\n");
    for(i=0;i<m;i++)
    {
        printf("字段ID:%-3d,%-11s,%-3d,%c\n",i+1,filde[i].fieldCaption,filde[i].fieldLen,filde[i].fieldType);
        sum=sum+filde[i].fieldLen;
    }
    printf("%d\n",sum);
    I.length=sum;
    printf("按任意键,可以录入信息\n");
    getch();
    system("cls");
    /*录入各字段的信息*/
    char *p=(char *)calloc(sum*n,sizeof(char));//申请一片连续内存,sum相当于存储一个同学数据所需要的最大字节数,n是同学人数,可理解为一个二维数组
    int flag=0;
    int num,numbur=0;
    for(j=0;j<n;j++)
    {
        num=0;
        for(i=0;i<m;i++)
        {

            printf("%s=",filde[i].fieldCaption);
            if(filde[i].fieldType=='s')
                scanf("%s",p+j*sum+num);
            else
                scanf("%d",(int *)(p+j*sum+num));//此处需要用(int*)进行强转
            num=num+filde[i].fieldLen;//num用于累加每录入一个同学数据时,一种一种字段类型所占字节数向下累加,并在每次循环开始前初始化为零
        }
        numbur++;
        I.jilu=numbur;
        printf("一条记录录入完毕!按任意键继续录入,按ESC键返回\n");
        if(getch()==27)
        {
            flag=1;
            system("cls");
            break;
        }
        else
            continue;


    }
    if(flag==0)
    {
        printf("已经录入完了最后一条记录,按任意键可浏览输入的数据");
        getch();

    }
    system("cls");
    printf("已经录入的信息:\n");
    for(j=0;j<numbur;j++)//此处边际值用numbur控制而没有用n的目的是,保证中途esc退出后不会打印出剩余未录入内容但已分配内存的学生信息段
    {
        num=0;
        for(i=0;i<m;i++)
        {
            if(filde[i].fieldType=='s')
                printf("%s:%s\t",filde[i].fieldCaption,p+j*sum+num);//利用%s输出字符串时,给地址值即可,不需要解引用
            else
                printf("%s:%d\t",filde[i].fieldCaption,*(int *)(p+j*sum+num));//输出时也需要用(int*)进行强转,并且解引用
            num=num+filde[i].fieldLen;
        }
        printf("\n");
    }
    printf("请输入要创建的文件名:");
    scanf("%s",filename);
    fp=fopen(filename,"w");
    fwrite(&I,sizeof(I),1,fp);
    fwrite(filde,sizeof(F),m,fp);
    fwrite(p,sum*n,1,fp);
    fclose(fp);
    printf("文件已创建,按任意键退出。。。");
    getch();
    exit(0);
   }
    else if(ch=='l'||ch=='L')
    {
        int k,num;
        printf("请输入要浏览的文件名:");
        scanf("%s",findfilename);
        fs=fopen(findfilename,"r");
        if(fs==NULL)
        {
            printf("文件不存在,按任意键退出程序。。。");
            getch();
            exit(0);
        }
        fread(&I,sizeof(I),1,fs);
        printf("以下是从文件中读出的信息:\n");
        printf("记录数为:%d,字段数量:%d,每条记录的长度为:%d\n\n",I.jilu,I.ziduan,I.length);
        fread(filde,sizeof(F),I.ziduan,fs);
        printf("表文件中字段的数据信息:\n\n");
        for(k=0;k<I.ziduan;k++)
        {
            printf("字段ID:%-3d,%-11s,%-3d,%c\n",k+1,filde[k].fieldCaption,filde[k].fieldLen,filde[k].fieldType);
            sum=sum+filde[k].fieldLen;
        }
        printf("\n");
        printf("表文件中的记录信息:\n\n");
        char *pr=(char *)calloc(sum*I.jilu,sizeof(char));
        fread(pr,sum*I.jilu,1,fs);
        for(j=0;j<I.jilu;j++)
        {
          num=0;
          for(i=0;i<I.ziduan;i++)
          {
            if(filde[i].fieldType=='s')
                printf("%s:%s\t",filde[i].fieldCaption,pr+j*sum+num);
            else
                printf("%s:%d\t",filde[i].fieldCaption,*(int *)(pr+j*sum+num));
            num=num+filde[i].fieldLen;
           }
           printf("\n");
         }
         printf("\n");
         free(pr);
         fclose(fs);
         printf("程序执行完毕,按任意键退出程序。。。\n");
         getch();
         exit(0);
    }
    else
    {
        exit(0);
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值