c理论期末预习(自定义数据类型,学生管理系统,链表,文件)

1.自定义数据类型

1.结构体

//define
struct a {
    int num;
    int cnt;
    struct a *next;
}a1,a2,a3;

struct b{
    int num;
    int cnt;
}b1,b2; //在定义对象的同时定义变量

typedef struct c{
    int num;
    int cnt;
    //struct c c2; //无限递归
    //my_c c3; //还未开始定义
    struct b b1;
}my_c; //equal typedef struct c my_c;

int main(){
    my_c c1[10];
    c1[1].num = 1; //equal struct a c1[10];

    //init
    my_c c11 = {1,2,{1,1}};
    my_c c3 = {9,1,{1,1}}; //结构体自身包含结构体就可以不用大括号了
    c11 = c3; //竟然可以赋值
    printf("%d %d %d %d",c11.num,c11.cnt,c11.b1.num,c11.b1.cnt);

    //结构体指针
    my_c *p = &c1; //注意要取地址,名称不像数组可以代表地址
    (*p).num = 5;
    p -> num = 6;
    p -> num ++; //(p -> num)++
    a1.next = &a2;
    a2.next = &a3;
    a1.next -> next -> num = 6;
    (*(*a1.next).next).num = 10;
    (*(a1.next -> next)).num = 11;

    //结构体数组的指针
    p = c1;
    (*(p + 1)).num = 8; //.的优先级更高
    (p + 1) -> num = 7; //地址 -> 类型成员

    //结构体传参
    //注意返回局部对象指针会导致所指地址上的内容被清空  

2.共用体

 //共用体
    union id{
        int num;
        char str[20];
    }id1,id2;
    //共用体数组,指针,传参
    union id* ptrId = &id1;
    union id allId[10];
    for(int i = 0;i < 10;i++){
        int temp;
        scanf("%d",&temp);
        (allId + i) -> num = temp;
    }

3.枚举

//枚举
    enum my_favorite_color{
        green,yellow,white,black
    }Lily,Daming,Laogou;

    typedef enum {
        Zhangsan,miemie,Coco
    }Friends; //给整型数据一个更易读的名字

    Friends my_friends = Coco;
    printf("%d",my_friends);

4.位域

//位域
 //限制union或者struct中,bit位数的多少
 struct d{
     unsigned char CLK : 3;
     unsigned char A : 4;
 }my_d;

 my_d.CLK = 2;
 my_d.A = 15;
 my_d.A >>= 2;

5.typedef

//typedef
 //将类型下的一个变量名设置为该类型的一个通用名
 typedef char *ptr_char;
 ptr_char p1,p2;
 //ptr_char = id1.str; //这同时意味着这个通用名称不再作为变量,进行赋值等操作

-----------------------室友的饭好香好香好香,我要吃饭了:(-------------------------

2.学生管理系统(链表)

上传了压缩包,里面有烂尾的系统(doge

3.文件

1.以只读模式打开文件

void file_read(){
    FILE *fp = fopen("./touch.txt","r");

    if(fp == NULL){
        perror("open file failed");
        return;
    }

    //read
    while(!feof(fp)){
        char ch = fgetc(fp);
        /* if(ch == EOF){
            //等价于 if(feof(fp))
      
            printf("\n");
            break;
        } */
        printf("%c",ch);
    }
    
    fclose(fp);
}

2.从stdin写入内容到文件中

void file_write(){
    FILE *fp = fopen("./touch1.txt","w");
    if(fp == NULL){
        perror("failed");
        return;
    }
    //write
    char str[30];
    while(!feof(fp)) fgets(str,30,stdin);
    //把换行符也读进去了,但是这样会一直读取
    //stdin表示文件流
    fputs(str,fp);
    fclose(fp);
}

3.同时读写

没什么特别的,只是引入了几个关于文件的函数

void file_read_write(){
    FILE *fp = fopen("./touch2","w+");
    if(fp == NULL){
        perror("failed");
        return;
    }
    //write
    char str[30];
    char *re_str =  fgets(str,30,stdin);
    int fpret = fputs(str,fp);//成功就是0
    printf("%d\n",fpret);

    //read1
    fputs(re_str,stdout);

    //read2
    printf("the second methods\n");
    rewind(fp);//将指针指向文件开头的地方
    char str2 [30];
    fgets(str2,30,fp);
    fputs(str2,stdout);

    fclose(fp);
}

4.标准的写入和读取

void file_fwrite(){
   FILE *fp = fopen("./touch4","w");
   if(fp == NULL){
       perror("failed");
       return;
   }
   //write1
   char str[30];
   fgets(str,30,stdin);
   fputs(str,fp);
   //write2
   fprintf(fp,"%s\t%s\t%s\t%s\n","okok","haha","emmm","fine");
   fclose(fp);
}
void file_fread(){
    FILE *fp = fopen("./touch3","r");
    if(fp == NULL){
        perror("failed");
        return;
    }
    char *info [4];
    //read1
    while(!feof(fp)){
        fscanf(fp,"%s %s %s %s",info[0],info[1],info[2],info[3]);
        printf("%s %s %s %s\n",info[0],info[1],info[2],info[3]);
    }
    //read2
    char str4[30];
    while(!feof(fp)){
        fgets(str4,30,fp);
        sscanf(str4,"%s%s%s%s",info[0],info[1],info[2],info[3]);
    }
    fclose(fp);
}

5.文件的拷贝

在read的同时write而已

void file_copy(char *fileName,char *name){
    FILE *fp = fopen(fileName,"r");
    if(fp == NULL){
        perror("failed");
        return;
    }
    //char name[30];
    /*copy_name(fileName,name);
    strcat(name,"-副本.txt");*/

    FILE *fp_new = fopen(name,"w");
    char str[100];
    while(!feof(fp)){
        fgets(str,100,fp);
        fputs(str,fp_new);
    }
    fclose(fp);
}
  • 如果你想更专业一点的话,可以看看这个名称提取的函数
void copy_name(char *fileName,char *str){
    char *beg = strchr(fileName,'/') + 1;
    char *end = strchr(fileName,'.');
    strncpy(str,beg,end - beg);
}

5. 命令行参数

int main(int argc,char *argv[]){
    printf("%d",argc);
    char *str1 = argv[1];
    char *str2 = argv[2];
    //file_read();
    //file_write();
    //file_read_write();
    //file_fwrite();
    file_copy(str1,str2);
}

  • 这里字符串 .\read touch new 字符串就是在shell里面人为给出的分别代表 运行可执行文件read touch和new被我用作了文件名称(file_copy里面)

6.补充几个函数

1.关于二进制文件
fopen(char *filename,"wb");
//ab表示追加,从前一个文件末尾添加
//b即为binary
//rb wb+ ab+
2.fwrite fread
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
3.fgetc fputc putc getc
int putc(int char, FILE *stream);
int getc(FILE *stream);
int fputc(int char, FILE *stream);
int fgetc(FILE *stream);
4.fseek ftell
long ftell(FILE *stream);
int fseek(FILE *stream, long offset, int whence);
//whence 可用SEEK_END SEEK_CUR SEEK_SET 或者分别对应的2 1 0替代
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值