• C语言学习10:结构体,结构体应用,联合用法,枚举,fopen函数使用,fseek,ftell的作用和文件结束符EOF,数组和文件交换数据,个人信息管理。


    1,结构体以及两种用法

    #include <stdio.h> 
    
    struct s { 
        int a; 
        int b; 
        char s[6]; 
    }; //结构体声明
    
    int main(void) 
    { 
        struct s obj={ 
            .a=5, 
            .b=8, 
            .s="hello", 
        }; //结构体初始化
    
        printf("sizeof obj=%u
    ",sizeof obj); //结果为16是两个int型占8个字节,最后一个数组要凑齐被4整除的边界只能是8,所以有16个字节。
        printf("&obj = %p,&obj.a=%p,&obj.b=%p
    " "&obj.s=%p,obj.s=%p
    ",&obj,&obj.a,&obj.b,&obj.s,obj.s); 
    
        printf("-------------------------
    "); 
            //obj.s类型等同于 char * 
        //&obj.s类型等同于  char (*)[6] 
        printf("obj.s=%p,obj.s+1=%p
    ",obj.s,obj.s+1); 
        printf("&obj.s=%p,&obj.s+1=%p
    ",&obj.s,&obj.s+1); 
        printf("------------------------
    "); 
        //.是域(field)运算符/取成员运算符 
        printf("obj.a=%d,obj.b=%d,obj.s=%s
    ",obj.a,obj.b,obj.s); 
        printf("==========================="); 
         
        //结构体取法 
        struct s *pobj = NULL; 
        pobj=&obj; 
    
        printf("sizeof pobj=%u
    ",sizeof pobj); 
            printf("&pobj = %p,pobj = %p,&obj=%p
    ",&pobj,pobj,&pobj); 
        printf("&pobj = %p,&pobj->a=%p,&pobj->b=%p
    " "&pobj->s=%p,pobj->s=%p
    ",&pobj,&pobj->a,&pobj->b,&pobj->s,pobj->s); 
    
        printf("---------------------------------
    "); 
        printf("pobj->s=%p,pobj->s+1=%p
    ",pobj->s,pobj->s+1); 
        printf("&pobj->s=%p,&pobj->s+1=%p
    ",&pobj->s,&pobj->s+1); 
        printf("------------------------
    "); 
        //->是域运算符/取成员运算符 
        printf("pobj->a=%d,pobj->b=%d,pobj->s=%s
    ",pobj->a,pobj->b,pobj->s); 
    
        return 0; 
    }

    结果:

    will@will-laptop:~/ex/9$ ./a.out 
    sizeof obj=16 
    &obj = 0xbeb79174,&obj.a=0xbeb79174,&obj.b=0xbeb79178 
    &obj.s=0xbeb7917c,obj.s=0xbeb7917c 
    ------------------------- 
    obj.s=0xbeb7917c,obj.s+1=0xbeb7917d 
    &obj.s=0xbeb7917c,&obj.s+1=0xbeb79182 
    ------------------------ 
    obj.a=5,obj.b=8,obj.s=hello 
    ===========================sizeof pobj=4 
    &pobj = 0xbeb79170,pobj = 0xbeb79174,&obj=0xbeb79170 
    &pobj = 0xbeb79170,&pobj->a=0xbeb79174,&pobj->b=0xbeb79178 
    &pobj->s=0xbeb7917c,pobj->s=0xbeb7917c 
    --------------------------------- 
    pobj->s=0xbeb7917c,pobj->s+1=0xbeb7917d 
    &pobj->s=0xbeb7917c,&pobj->s+1=0xbeb79182 
    ------------------------ 
    pobj->a=5,pobj->b=8,pobj->s=hello

    2,结构体应用

    #include <stdio.h> 
    #include <stdlib.h> 
    
    struct s { 
        int a; 
        int b; 
        char s[6]; 
    }; 
    
    int main(void) 
    { 
        struct s obj={ 
            .a=6, 
            .b=8, 
            .s="hello", 
        }; 
        printf("obj.a=%d,obj.b=%d,obj.s=%s
    ",obj.a,obj.b,obj.s); 
        printf("obj.a=%p,obj.b=%p,obj.s=%p
    ",&obj.a,&obj.b,&obj.s); 
        printf("------------------------
    "); 
    
        struct s obj_copy; 
        //同类型结构体对象之间可以直接复制 
        obj_copy = obj; 
        printf("obj_copy.a=%d,obj_copy.b=%d,obj_copy.s=%s
    ",obj.a,obj.b,obj.s); 
        printf("obj_copy.a=%p,obj_copy.b=%p,obj_copy.s=%p
    ",&obj.a,&obj.b,&obj.s); 
        printf("------------------------
    "); 
        struct s *pobj=NULL; 
        pobj = malloc(sizeof(struct s)); 
        if(NULL==pobj) 
            return 1; 
            //结果体对象之间复制是浅拷贝 
    //    pobj=&obj;这个是取地址,没有使用开辟的空间 
               *pobj = obj; 
        printf("pobj->a=%d,pobj->b=%d,pobj->s=%s
    ",pobj->a,pobj->b,pobj->s); 
        printf("pobj->a=%p,pobj->b=%p,pobj->s=%p
    ",&pobj->a,&pobj->b,&pobj->s); 
        free(pobj); 
        return 0; 
    }

    结果:

    will@will-laptop:~/ex/9$ ./a.out 
    obj.a=6,obj.b=8,obj.s=hello 
    obj.a=0xbe869164,obj.b=0xbe869168,obj.s=0xbe86916c 
    ------------------------ 
    obj_copy.a=6,obj_copy.b=8,obj_copy.s=hello 
    obj_copy.a=0xbe869164,obj_copy.b=0xbe869168,obj_copy.s=0xbe86916c 
    ------------------------ 
    pobj->a=6,pobj->b=8,pobj->s=hello 
    pobj->a=0x7ee008,pobj->b=0x7ee00c,pobj->s=0x7ee010 

    3,联合用法

    #include <stdio.h> 
    
    union u{ 
        int a; 
        char ch; 
        double d; 
    }; 
    
    int main(void) 
    { 
           union u uobj; 
           union u *pu=NULL; 
    
           pu=&uobj; 
           printf("sizeof uobj=%u
    ",sizeof uobj); 
           //选取最大的大小,也就是双精度的八位
           uobj.a = 3; 
           printf("uobj.a=%d
    ",uobj.a); 
           printf("uobj.d=%lf
    ",uobj.d); //未初始化直接变成0
           printf("---------------
    "); 
    
           printf("&uobj.a=%p,&uobj.ch=%p
    ""&uobj.d=%p,&uobj=%p
    ",&uobj.a,&uobj.ch,&uobj.d,&uobj);

    //这个说明位置没有根本变化,只能拿一个出来用, uobj.d=3.14; printf("uobj.d=%lf ",uobj.d); printf("uobj.a=%d ",uobj.a); //越界了a的值不对了。如果要使用a的值就需要在打印完后再自行赋值 printf("--------------- "); uobj.ch='A'; printf("uobj.ch=%c ",uobj.ch); printf("&uobj.a=%p,&uobj.ch=%p ""&uobj.d=%p,&uobj=%p ",&uobj.a,&uobj.ch,&uobj.d,&uobj); //结果表明每一调出的元素都是相同的地址,联合是提供了不同的元素 printf("--------------- "); printf("&pu->a=%p,&pu->ch=%p ""&pu->d=%p,pu=%p ",&pu->a,&pu->ch,&pu->d,pu); //pu本身是存储地址的指针而已,所以不用取地址符 return 0; }

    结果:

    will@will-laptop:~/ex/9$ ./a.out 
    sizeof uobj=8 
    uobj.a=3 
    uobj.d=0.000000 
    --------------- 
    &uobj.a=0xbe8d1188,&uobj.ch=0xbe8d1188 
    &uobj.d=0xbe8d1188,&uobj=0xbe8d1188 
    uobj.d=3.140000 
    uobj.a=1374389535 
    --------------- 
    uobj.ch=A 
    &uobj.a=0xbe8d1188,&uobj.ch=0xbe8d1188 
    &uobj.d=0xbe8d1188,&uobj=0xbe8d1188 
    --------------- 
    &pu->a=0xbe8d1188,&pu->ch=0xbe8d1188 
    &pu->d=0xbe8d1188,pu=0xbe8d1188 

    4,枚举

    #include <stdio.h> 
    //枚举就是将变量的值一一列举出来, 
    //变量的值只限于列举出来的值的范围内 
    enum txt_attr { 
        color_start,//0 
        black,//1 
        white, 
        red, 
        yellow, 
        blue, 
        green, 
        orange, 
        color_end =32, 
    
        attr_start, 
        italic, 
        bold, 
        attr_end 
    }; 
    
    int main(void) 
    { 
        enum txt_attr txt; 
    
        txt = color_start; 
        printf("color_start = %d
    ",txt); 
        txt=black; 
        printf("black       = %d
    ",txt); 
        txt=orange; 
        printf("orange      = %d
    ",txt); 
            txt=color_end; 
        printf("color_end   = %d
    ",txt); 
    
        printf("---------------------------
    "); 
    
        txt=attr_start; 
        printf("attr_start  = %d
    ",txt);//枚举就是排序有代号 
        printf("attr_start  = %d
    ",attr_start); 
    
        txt=italic; 
        printf("italic      =%d
    ",txt);//会自动加1,如果没有定义的话 
    
        return 0; 
    }

    结果:

    will@will-laptop:~/ex/9$ ./a.out 
    color_start = 0 
    black       = 1 
    orange      = 7 
    color_end   = 32 
    --------------------------- 
    attr_start  = 33 
    attr_start  = 33 
    italic      =34 

    5,fopen函数使用

    #include <stdio.h> 
    #include <errno.h> 
    
    int main(void) 
    { 
        FILE *fp=NULL; 
        size_t ret=0; 
    
        fp=fopen("1.txt","w+");//打开文件,因为有w+没有就创建 
        if(NULL==fp) 
        { 
            //perror:根据errno解释错误原因并输出到stderr 
            //perror("fopen failed"); 
    
            //strerror:根据errno返回错误原因的字符串描述 
            fprintf(stderr,"fopen failed,%s
    ",strerror(errno)); 
    //错误标识语句
    goto err0; } ret=fwrite("china unix",1,10,fp); if(ret!=10) { fprintf(stderr,"fwrite failed,%s ",strerror(errno)); goto err1; } printf("------file writed,now read file------- "); rewind(fp); //文件内部位置指针指向开头 char s[32]={0}; ret=fread(s,1,10,fp); if(ret!=10) { perror("fread failed");//这个是固定用的 goto err1; } printf("now readed.s = %s ",s); fclose(fp); return 0; err1: fclose(fp); err0: return 1; }

    结果:

    will@will-laptop:~/ex/9$ sudo ./a.out
    [sudo] password for will: 
    ------file writed,now read file------- 
    now readed.s = china unix 

    6,fseek,ftell的作用和文件结束符EOF

    #include <stdio.h>
    
    int main(void)
    {
        FILE *fp = NULL;
        size_t ret;
        int pos;
    
        fp = fopen("files/2.txt", "w+");
        if (NULL == fp)
        {
            perror("fopen failed");    
            goto err0;
        }
    
        pos = ftell(fp);//获得相对于文件首的偏移字数
        printf("file opened, pos = %d
    ", pos);
    
        ret = fwrite("china", 1, 5, fp);
        if (5 != ret)
        {
            perror("fwrite failed");    
            goto err1;
        }
        printf("------'china' writed, pos = %d
    ", ftell(fp));
    
        fseek(fp, 6, SEEK_CUR);//定位到文件头六个字节后
        pos = ftell(fp);
        printf("------fseek 6 bytes. pos = %d
    ", pos);
    
        ret = fwrite(" unix", 1, 5, fp);
        if (5 != ret)
        {
            perror("fwrite failed");    
            goto err1;
        }
        printf("------' unix' writed, pos = %d
    ", ftell(fp));
    
        rewind(fp);
    
        printf("read file and print now:
    ");
        int ch;
        printf("EOF == %d
    ", EOF);//文件结束符的值是-1
        while ((ch = fgetc(fp)) != EOF)//循环输出文件内容
            putchar(ch);
        putchar('
    ');
    
        fclose(fp);
    
        return 0;
    err1:
        fclose(fp);
    err0:
        return 1;
    }

    结果:

    file opened, pos = 0
    ------'china' writed, pos = 5
    ------fseek 6 bytes. pos = 11
    ------' unix' writed, pos = 16
    read file and print now:
    EOF == -1
    china unix

    7,数组和文件交换数据

    #include <stdio.h> 
    
    void rand_a(int *p,int len) 
    { 
        int i; 
        for(i=0;i<len;i++) 
            p[i]=rand()%100; 
    } 
    
    void print_a(int *p,int len) 
    { 
        int i; 
        for(i=0;i<len;i++) 
        { 
            printf("%d  ",p[i]); 
        } 
        putchar('
    '); 
    } 
    
    int main(void) 
    { 
        FILE *fp=NULL; 
        int a[10]={0}; 
        int b[10]={0}; 
    
        fp=fopen("3.int","w+"); 
        if(NULL==fp) 
        { 
            perror("fopen failed"); 
            goto err0; 
        } 
    
        rand_a(a,10); 
        printf("a:
    "); 
        print_a(a,10); 
    
        fwrite(a,sizeof(int),10,fp); 
        fclose(fp); 
    
        printf("--------------------
    "); 
        fp=fopen("3.int","r"); 
        if(NULL==fp) 
        { 
                   perror("fopen failed"); 
               goto err0; 
        } 
         
        fread (b,sizeof(int),10,fp); 
        printf("b:
    "); 
        print_a(b,10); 
    
        fclose(fp); 
    
        return 0; 
    err0: 
        return 1; 
    }

    结果:

    will@will-laptop:~/ex/9$  ./a.out 
    a: 
    83  86  77  15  93  35  86  92  49  21  
    -------------------- 
    b: 
    83  86  77  15  93  35  86  92  49  21  

    8,个人信息管理

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
    typedef struct _basic{ 
        int id; 
        char sex; 
        char name[32]; 
    }basic_t; 
    
    typedef struct _contact { 
        char qq[16]; 
        char email[]; 
    }contact_t; 
    
    typedef struct _person{ 
            struct _basic binfo; 
            contact_t *pcont; 
    }person_t; 
    
    int add_person(person_t **p,int *cnt) 
    { 
            p[*cnt]=malloc(sizeof(person_t)); 
        if(NULL==p[*cnt]) 
            goto err0; 
        p[*cnt]->pcont =malloc(sizeof(contact_t)); 
        if(NULL==p[*cnt]->pcont) 
            goto err1; 
        p[*cnt]->binfo.id=rand()%100; 
        p[*cnt]->binfo.sex ="MF"[rand()%2]; 
        printf("	input name:"); 
        gets(p[*cnt]->binfo.name); 
    
        printf("	input qq:"); 
        gets(p[*cnt]->pcont->qq); 
        printf("	input email:"); 
        gets(p[*cnt]->pcont->email); 
    
        *cnt +=1; 
    
        return 0; 
    err1: 
        free(p[*cnt]); 
        p[*cnt]=NULL; 
    err0: 
        return -1; 
    } 
    
    void print_person(person_t **p,int cnt) 
    { 
        int i; 
        for(i=0;i<cnt;i++) 
        { 
            printf("	---第%d人信息:---
    ",i+1); 
            printf("	id:%d sex:%c name:%s
    ",p[i]->binfo.id,p[i]->binfo.sex,p[i]->binfo.name); 
            printf("	qq:%s email:%s
    ",p[i]->pcont->qq,p[i]->pcont->email); 
        } 
    
         
    } 
    
    int save_person(person_t **p ,int cnt) 
    { 
        FILE *fp = NULL; 
        size_t ret; 
        int i; 
        if(NULL==(fp=fopen("person.db","w"))) 
        { 
            perror("fopen"); 
            goto err0; 
        } 
        if(1!=(ret=fwrite(&cnt,sizeof(int),1,fp))) 
            goto err1; 
        for(i=0;i<cnt;i++) 
        { 
            if(1!=fwrite(p[i],sizeof(person_t),1,fp)) 
                goto err1; 
            if(1!=fwrite(p[i]->pcont,sizeof(contact_t),1,fp)) 
                goto err1; 
        } 
        fclose(fp); 
    
        return 0; 
    err1: 
        fclose(fp); 
    err0: 
        return -1; 
    } 
    
    int load_person(person_t **p,int *cnt) 
    { 
        FILE *fp=NULL; 
        int i,j,count; 
        for(i=0;i<*cnt;i++) 
        { 
            free(p[i]->pcont); 
            free(p[i]); 
        } 
    
        if(NULL==(fp=fopen("person.db","r"))) 
            perror("fopen"); 
            goto err0; 
        if(1!=fread(&count,sizeof(int),1,fp)) 
            goto err1; 
        for(i=0;i<count;i++) 
        { 
            p[i]=malloc(sizeof(person_t)); 
            if(NULL==p[i]) 
                goto err2; 
            if(1!=fread(p[i],sizeof(person_t),1,fp)) 
                goto err2; 
    
            p[i]->pcont=malloc(sizeof(contact_t)); 
            if(NULL==p[i]) 
                goto err3; 
            if(1!=fread(p[i]->pcont,sizeof(contact_t),1,fp)) 
                goto err3; 
    
        } 
        *cnt=count; 
        fclose(fp); 
    
        return 0; 
    err3: 
        free(p[i]); 
    err2: 
        for(j=0;j<i;j++) 
        { 
            free(p[i]->pcont); 
            free(p[j]); 
            p[j]=NULL; 
        } 
    err1: 
        fclose(fp); 
    err0: 
            return -1; 
    
    } 
    
    int main(void) 
    { 
        person_t *pers[10]={NULL}; 
        printf("	====>欢迎光临个人信息管理系统<====
    "); 
    
        int quit =0,ret,op; 
        int i,count=0; 
        while(!quit) 
        { 
    retry: 
            printf("	===>1.输入个人信息
    "); 
            printf("	===>2.遍历个人信息
    "); 
            printf("	===>3.存储个人信息
    "); 
            printf("	===>4.读取个人信息
    "); 
            printf("	===>5.退出
    "); 
            printf("	===>请选择【1-5】"); 
    
            ret=scanf("%d",&op); 
            while(getchar()!='
    ') 
                ; 
            if(ret==0) 
            { 
                printf("	输入错误
    "); 
            } 
            switch (op) 
            { 
                case 1: 
                    if(count >= 10) 
                    { 
                        printf("	只能存放10个个人信息!
    "); 
                        break; 
                    } 
                    if(0==add_person(pers,&count)) 
                        printf("	 添加成功!
    "); 
                    else 
                        printf("添加失败
    "); 
                    case 2: 
                    print_person(pers,count); 
                    break; 
                case 3: 
                    if(0==save_person(pers,count)) 
                        printf("	保存成功
    "); 
                    else 
                        printf("保存失败
    "); 
                    break; 
                case 4: 
                    if(0==load_person(pers,&count)) 
                        printf("读取成功
    "); 
                    else 
                        printf("读取失败
    "); 
                    break; 
                case 5: 
                    quit =  1; 
                    break; 
                default: 
                    break; 
            } 
        } 
        for(i=0;i<count;i++)//循环结束,就必须释放空间内存 
        { 
            free(pers[i]->pcont); 
            free(pers[i]); 
        } 
        return 0; 
    } 

    结果:

    ===> 欢迎光临个人信息管理系统 <===
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: 1
        input name: a 
        input qq: 123
        input email: asd
        添加成功!
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: 1
        input name: 2
        input qq: 2
        input email: 
        添加成功!
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: 2
        --- 第 1 人信息: ---
        id: 83 sex: M name: a
        qq: 123 email: asd
        --- 第 2 人信息: ---
        id: 77 sex: F name: 2
        qq: 2 email: 
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: 3
        保存成功!
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: 4
        读取成功!
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: ^C
    will@will-Inspiron-N4010:~/uplooking/c/9th$ ./a.out
    ===> 欢迎光临个人信息管理系统 <===
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: 4
        读取成功!
    ====> 1. 输入个人信息 <====
    ====> 2. 遍历个人信息 <====
    ====> 3. 存储个人信息 <====
    ====> 4. 读取个人信息 <====
    ====> 5. 退出         <====
    ==> 请选择[1 - 5]: 2
        --- 第 1 人信息: ---
        id: 83 sex: M name: a
        qq: 123 email: asd
        --- 第 2 人信息: ---
        id: 77 sex: F name: 2
        qq: 2 email: 
  • 相关阅读:
    微软小娜APP的案例分析
    嵌入式第12次实验
    嵌入式第11次实验
    嵌入式第10次实验报告
    嵌入式第9次实验
    软工 小组作业(第二次)
    嵌入式软件设计第8次实验报告-140201236-沈樟伟
    5月17下
    5月17上
    5月15上午
  • 原文地址:https://www.cnblogs.com/will-boot/p/3355093.html
Copyright © 2020-2023  润新知