C语言进阶:文件操作,学生信息管理系统

2023-11-15

1. 重定向

重定向文件输出:
把运行出来的内容直接保存在文件中 ./a.out > hello.txt

#include <stdio.h>

int main(){
        printf("hallo\n");
}

重定向执行结果:

[admin@localhost cfile]$ ./hi > hi.txt
[admin@localhost cfile]$ cat hi.txt 
hallo

重定向文件输入:
把文件中的内容给运行后的输入 ./a.out < hello.txt

#include <stdio.h>

int main(){
        char name[20];
        scanf("%s",name);
        printf("hallo %s\n",name);
}

重定向执行结果:

[admin@localhost cfile]$ ./hi < hi.txt
hallo hallo

其他执行情况:

[admin@localhost cfile]$ ./hi > hi.txt
123       
[admin@localhost cfile]$ cat hi.txt
hallo 123
[admin@localhost cfile]$ ./hi >> hi.txt
456
[admin@localhost cfile]$ cat hi.txt
hallo 123
hallo 456
[admin@localhost cfile]$ echo abc | ./hi
hallo abc

结构体存:
结构体输出重定向到文件中

#include <stdio.h>

typedef struct Student{
        char name[20];
        int age;
        float score;
}Stud;

int main(){
        Stud s1 = {"张三",23,98};
        printf("%s %d %f\n",s1.name,s1.age,s1.score);
}

结果为:

[admin@localhost cfile]$ ./hi1 > hi1.txt
[admin@localhost cfile]$ cat hi1.txt
张三 23 98.000000

结构体取:
结构体格式的文件内容重定向到程序输入中

#include <stdio.h>

typedef struct Student{
        char name[20];
        int age;
        float score;
}Stud;

int main(){
        Stud s1;
        scanf("%s%d%f",&s1.name,&s1.age,&s1.score);
        printf("%s %d %f\n",s1.name,s1.age,s1.score);
}

结果为:

[admin@localhost cfile]$ ./hi1 < hi1.txt
张三 23 98.000000
[admin@localhost cfile]$ ./hi1
李四 24 92.13
李四 24 92.129997
[admin@localhost cfile]$ ./hi1 > hi1.txt
李四 24 92.13
[admin@localhost cfile]$ cat hi1.txt
李四 24 92.129997

每次重定向输入会替换文件中的内容

2. 读文件和写文件

fscanf()   写文件
fprintf()   读文件
返回实际读取的数据个数,出错或者到结尾返回 EOF

stdin是标准读,从终端读取
stdout是标准写,从终端写

在终端写入文件后直接在终端读出

#include <stdio.h>

typedef struct Student{
        char name[20];
        int age;
        float score;
}Stud;

int main(){
        Stud s1;
        fscanf(stdin,"%s%d%f",&s1.name,&s1.age,&s1.score);
        fprintf(stdout,"%s %d %f\n",s1.name,s1.age,s1.score);
}

结果为:

张美丽 23 97
张美丽 23 97.000000

3. 打开文件和关闭文件

fopen()   打开文件
fclose()   关闭文件

基本框架:

 FILE* fp = fopen("文件路径","打开方式");
 if(NULL != fp){
        fclose(fp);         
 }       

打开方式:

NO. 打开方式 含义
1 r 读(默认文本文件)
2 w 写,如果这个文件不存在,就创建这个文件;如果这个文件存在,则清空内容
3 a 追加,如果这个文件不存在,就创建这个文件;如果这个文件存在,则在文件尾部追加内容
4 + 以可读可写的方式打开文件,配合r、w、a使用
5 t 文本文件
6 b 二进制文件

FILE是一种基于文件结构的变量类型,FILE* fp; 声明了 fp 是 FILE 型指针

读取文件中的学生信息:

#include <stdio.h>

typedef struct Student{
        char name[20];
        int age;
        float score;
} Stud;

int main(){
        FILE* pfile = fopen("hi1.txt","r");    //打开文件
        if(NULL == pfile){
                printf("file is not existed!\n");
                return 1;
        }

        int n;
        fscanf(pfile,"%d",&n);
        Stud s[n];
        for(int i=0;i<n;++i){
                fscanf(pfile,"%s%d%f",&s[i].name,&s[i].age,&s[i].score);
        }

        fclose(pfile);        //关闭文件

        for(int i=0;i<n;++i){
                fprintf(stdout,"%s %d %f\n",s[i].name,s[i].age,s[i].score);
        }
}

在 hi1.txt 文件中输入内容:

2
李四 24 92.129997
王五 23 90

输出结果为:

李四 24 92.129997
王五 23 90.000000

4. 综合大题:学生信息管理系统

功能:

进入页面显示文件内容加载情况,选择数字进入不同功能

  1. 查看所有学生信息
  2. 录入学生信息
  3. 按成绩排序
  4. 查询学生成绩
  5. 删除学生信息
  6. 以上功能完成则继续选择,输入0才退出
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

typedef struct Student{
        char name[20];
        int age;
        float score;
}Stud;

//从文件中加载学生信息
bool Load(const char* path,Stud s[],int* n){    //文件,读出来放s,个数

        FILE* pfile = fopen(path,"r");  //只读方式打开文件
        if(NULL == pfile){
                printf("file is not existed!\n");
                return false;
        }
        // 读取学生个数
        int m;
        fscanf(pfile,"%d",&m);
        *n = m;
        for(int i=0;i<m;++i){
                fscanf(pfile,"%s%d%f",&s[i].name,&s[i].age,&s[i].score);
        }
        fclose(pfile);  //关闭文件
        pfile = NULL;  //把指针清空,防止后续代码误用

        return true;
}

//把学生数据保存到文件中
bool Save(const char* path,const Stud* s,int n){
        FILE* pfile2 = fopen(path,"w");  //只写方式打开文件
        if(NULL == pfile2){
                printf("file stud.txt is not existed!\n");
                return false;
        }
        fprintf(pfile2,"%d\n",n);
        for(int i=0;i<n;++i){
                fprintf(pfile2,"%s %d %f\n",s[i].name,s[i].age,s[i].score);
        }
        fclose(pfile2);  //关闭文件
        pfile2 = NULL;  //把指针清空,防止后续代码误用

        return true;
}

//录入新信息
void Register(Stud* s,int*n){
        printf("请输入学生个数:");
        //新加学生个数
        int m;
        scanf("%d",&m);
        //新建一个表,并写入
        Stud t[m];
        for(int i=0;i<m;++i){
                scanf("%s%d%f",&t[i].name,&t[i].age,&t[i].score);
        }
        //把新信息加在原数据的后面
        for(int i=0;i<m;++i){
                s[*n+i] = t[i];
        }
        *n += m;
}

//显示所有已登记的所有学生信息
void ShowStudents(const Stud s[],int n){
        printf("姓名\t年龄\t成绩\n");
        for(int i=0;i<n;++i){
                printf("%s\t%d\t%f\n",s[i].name,s[i].age,s[i].score);
        }
}

//按成绩排序
int ScoreCmp(const void* a,const void* b){
        return((Stud*)b)->score - ((Stud*)a)->score;
}
void SortStudents(Stud s[],int n){
        qsort(s,n,sizeof(Stud),ScoreCmp);  //ScoreCmp为回调函数,qsort用来排序
}

//查找学生信息
void SearchStudent(const Stud s[],int n){
        printf("请输入学生姓名:");
        //先输一个名字给name[20]
        char name[20];
        scanf("%s",name);
        bool found = false; //标记,假设没找到
        for(int i=0;i<n;++i){
                if(strcmp(s[i].name,name)==0){
                        found = true;  //找到了,修改标记
                        printf("查询结果:");
                        printf("%s\t%d\t%f\n",s[i].name,s[i].age,s[i].score);
                }
        }
        if(!found){
                printf("查无此人\n");
        }
}

//删除学生信息
void DeleteStudent(Stud s[],int *n){
        printf("请输入学生姓名:");
        //先输一个名字给name[20]
        char name[20];
        scanf("%s",name);
        for(int i=0;i<*n;++i){
                //如果找到这个学生的名字
                if(strcmp(s[i].name,name)==0){
                        for(int j=i;j<*n;++j){
                                s[j]=s[j+1];   //直接把后面的信息补上来,替换掉
                        }
                        --*n;
                }
        }
}

//主函数
int main(){
        const char* data = "./stud.txt";
        Stud s[100];
        int n;
        if(Load(data,s,&n)){
                printf("已经加载成功%d学生信息\n",n);
        }
        while(true){
                printf("查看功能列表:\n");
                printf("1.查看所有学生信息\n");
                printf("2.录入学生信息\n");
                printf("3.按成绩排序\n");
                printf("4.查询学生成绩\n");
                printf("5.删除学生信息\n");
                printf("0.退出\n");
                printf("请选择功能:");
                int num;
                scanf("%d",&num);
                switch(num){
                        case 1:
                                ShowStudents(s,n);
                                break;
                        case 2:
                                Register(s,&n);
                                Save(data,s,n);
                                break;
                        case 3:
                                SortStudents(s,n);
                                ShowStudents(s,n);
                                break;
                        case 4:
                                SearchStudent(s,n);
                                break;
                        case 5:
                                DeleteStudent(s,&n);
                                Save(data,s,n);
                                break;
                        case 0:
                                return 0;
                        default:
                                printf("选项输入错误\n");
                                return 1;
                }
        }
}

文件存在且空时,结果为:

已经加载成功0学生信息
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:2
请输入学生个数:3
张三 25 85
李四 21 94
王五 23 91
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:1
姓名	年龄	成绩
张三	25	85.000000
李四	21	94.000000
王五	23	91.000000
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:3
姓名	年龄	成绩
李四	21	94.000000
王五	23	91.000000
张三	25	85.000000
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:4
请输入学生姓名:王五
查询结果:王五	23	91.000000
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:5
请输入学生姓名:李四
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:1
姓名	年龄	成绩
王五	23	91.000000
张三	25	85.000000
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:0

该程序在没有文件的情况下,如果录入信息,会新建文件 ./stud.txt

void Func(int arr[] , int n); 和 void Func(int* arr , int n); 两种写法完全一样

  1. char str[20] = “abcd”; 初始化字符数组
    char* s = str; 字符串指针,存放地址(字符数组地址),可以修改
  2. char* s = “abcd”; 初始化字符串指针,存放地址(字符串常量地址),不可以修改字符

s[0] = ‘b’; 当修改变量时,前者可以修改,后者则吐核

5. 二进制读文件和二进制写文件

fread()   二进制读
fwrite()   二进制写

使用结构:
fread(变量地址,变量长度,读的个数,从该文件读);
fwrite(变量地址,变量长度,写的个数,写到的文件);

上述问题下可以直接更改写文件(保存文件)

//把学生数据保存到文件中
bool Save(const char* path,const Stud* s,int n){
        FILE* pfile2 = fopen(path,"wb");  //只写方式打开文件
        if(NULL == pfile2){
                printf("file stud.txt is not existed!\n");
                return false;
        }
        fwrite(&n,sizeof(n),1,pfile2);
        //fprintf(pfile2,"%d\n",n);
        //for(int i=0;i<n;++i){
        //        fprintf(pfile2,"%s %d %f\n",s[i].name,s[i].age,s[i].score);
        //}
        fwrite(s,sizeof(Stud),n,pfile2);      //可以直接写结构体的内容

        fclose(pfile2);  //关闭文件
        pfile2 = NULL;  //把指针清空,防止后续代码误用

        return true;
}

主函数需要重新建立一个文件用来存二进制信息,每一步都Save给新文件
运行 ···
新录入学生的信息会以二进制的形式保存在新的文件中,我们查看时看不懂的

保存了一些数据后,可以进行二进制读取的操作

bool Load(const char* path,Stud s[],int* n){    //文件,读出来放s,个数

        FILE* pfile = fopen(path,"rb");  //只读方式打开文件
        if(NULL == pfile){
                printf("file is not existed!\n");
                return false;
        }
        // 读取学生个数
        int m;
        fread(&m,sizeof(m),1,pfile);
        //fscanf(pfile,"%d",&m);
        *n = m;
        //for(int i=0;i<m;++i){
        //      fscanf(pfile,"%s%d%f",&s[i].name,&s[i].age,&s[i].score);
        //}
        fread(s,sizeof(Stud),m,pfile);

        fclose(pfile);  //关闭文件
        pfile = NULL;  //把指针清空,防止后续代码误用

        return true;
}

修改主函数中 Load 应加载的新文件
运行···
这样之前的功能就能照常使用了,只不过文件中的二进制内容我们看不懂

用二进制读写文件做学生信息管理系统
整体程序可参考文章《C语言进阶:学生信息管理系统的不断优化,大块程序拿去用》第2部分

6. 文件定位

获取位置(在本文第几个字节): ftell(文件指针)
设置位置(指向第几个字节): fseek(文件指针,偏移量,起始点)

起始点 含义 代表数值
SEEK_SET 从头开始 0
SEEK_CUR 从当前开始 1
SEEK_END 从结束开始 2

查看多个文件的大小(字节数):

#include <stdio.h>

int main(int argc,char* argv[]){
        if(argc == 1){
                printf("error:no argument\n");
                printf("Usage:%s filepath ...",argv[0]);
                return 1;
        }

        for(int i=1;i<argc;++i){
                FILE* pf = fopen(argv[i],"r");
                if(NULL == pf){
                        printf("error:open %s fail\n",argv[i]);
                        return 1;
                }

                fseek(pf,0,SEEK_END);
                printf("%s %d\n",argv[i],ftell(pf));

                fclose(pf);
                pf = NULL;
        }
}

结果为:

[admin@localhost cfile]$ ./sizeof ../note/*
../note/2021-3-1 LU1笔记 4145
../note/2021-3-2 LU2笔记 7513
../note/2021-3-4LU3笔记 2028
../note/C1 5714
../note/C10 2318
../note/C11 443
../note/C2 7808
../note/C3 8972

文件定位函数的应用:
当数据量很大时,用文件定位,每次修改信息时,不用重新刷新信息
把指针指在要改学生信息的开头:
fseek(fp , sizeof(int)+sizeof(Stud)*i , SEEK_SET);

优化学生管理系统:用文件定位函数增加学生信息、修改学生信息
详细应用请看文章《C语言进阶:学生信息管理系统的不断优化,大块程序拿去用》第2部分

7. 其他文件操作函数

文件结尾判断
feof(pf)     pf 指针是否在文件结尾处
读完文件返回1,没读完就返回0

学生信息文件中不写学生个数,只用 n 做统计:

//从文件中加载学生信息
bool Load(const char* path,Stud s[],int* n){    //文件,读出来放s,个数

        FILE* pfile = fopen(path,"r");  //只读方式打开文件
        if(NULL == pfile){
                printf("file is not existed!\n");
                return false;
        }
        // 读取学生个数
        int i=0;
        for(;;){       // while(!feof(pfile)){  到文件结尾处才停止
                int res = fscanf(pfile,"%s%d%f",&s[i].name,&s[i].age,&s[i].score);
                if(EOF == res) break;
                ++i;
        }
        *n = i;       // *n = i-1;  表示feof读多了一个值,所以要减1

        fclose(pfile);  //关闭文件
        pfile = NULL;  //把指针清空,防止后续代码误用

        return true;
}

//把学生数据保存到文件中
bool Save(const char* path,const Stud* s,int n){
        FILE* pfile2 = fopen(path,"w");  //只写方式打开文件
        if(NULL == pfile2){
                printf("file stud.txt is not existed!\n");
                return false;
        }
        for(int i=0;i<n;++i){
                fprintf(pfile2,"%s %d %f\n",s[i].name,s[i].age,s[i].score);
        }
        fclose(pfile2);  //关闭文件
        pfile2 = NULL;  //把指针清空,防止后续代码误用

        return true;
}

返回文件开头
rewind(pf)     返回文件开头
效果和 fseek(pf,0,SEEK_SET); 一样

清空数据流
fflush(fp)     清空数据流

文件重命名和文件删除
int rename(const char* 旧文件名 , const char* 新文件名);     文件重命名
int remove(char* 要删除的文件名);     文件删除

8. 系统再优化之用户登录与注册

增加用户注册和登录功能:

结构体 User 定义用户信息
main 函数在进入功能时要更改
bool RegisterUser 函数用于注册
bool Login 函数用于登陆

以下程序为有关注册和登录的部分程序

//用户信息所用结构体
typedef struct User{
        char name[20];
        char password[6];  //密码6位
} User;

//录入注册信息
bool RegisterUser(const char* path){
        printf("首次登陆需要注册\n");
        User current;
        printf("注册用户名:");
        scanf("%s",current.name);
        printf("注册密码:");
        scanf("%s",current.password);

        FILE* pf = fopen(path,"w");
        if(NULL == pf){
                return false;
        }
        fprintf(pf,"%s %s",current.name,current.password);
        fclose(pf);
        pf = NULL;
        return true;
}

//验证用户和密码是否正确
bool Login(const char* path){
        FILE* pf = fopen(path,"r");
        if(NULL == pf){    //如果没存过用户信息,则存用户信息
                return RegisterUser(path);    //第一次登陆要注册,注册成功直接进入
        }
        printf("Login...\n");
        User current;
        printf("请输入用户名:");
        scanf("%s",current.name);
        printf("请输入密码:");
        scanf("%s",current.password);

        for(;;){
                User user;
                int res = fscanf(pf,"%s%s",user.name,user.password);
                if(EOF == res) break;
                if(strcmp(current.name,user.name)==0 && strcmp(current.password,user.password)==0){return true;}
        }
        return false;
}

//主函数
int main(){
        const char* data = "./stud.txt";
        const char* user = "./user.txt";

        if(!Login(user)){
                printf("error login\n");
                return 1;
        }

        Stud s[100];
        int n;
        if(Load(data,s,&n)){
                printf("已经加载成功%d学生信息\n",n);
        }
        while(true){
                printf("查看功能列表:\n");
                printf("1.查看所有学生信息\n");
                printf("2.录入学生信息\n");
                printf("3.按成绩排序\n");
                printf("4.查询学生成绩\n");
                printf("5.删除学生信息\n");
                printf("0.退出\n");
                printf("请选择功能:");
                int num;
                scanf("%d",&num);
                switch(num){
                        case 1:
                                ShowStudents(s,n);
                                break;
                        case 2:
                                Register(s,&n);
                                Save(data,s,n);
                                break;
                        case 3:
                                SortStudents(s,n);
                                ShowStudents(s,n);
                                break;
                        case 4:
                                SearchStudent(s,n);
                                break;
                        case 5:
                                DeleteStudent(s,&n);
                                Save(data,s,n);
                                break;
                        case 0:
                                return 0;
                        default:
                                printf("选项输入错误\n");
                                return 1;
                }
        }
}

整体运行结果为:

[admin@localhost cfile]$ ./file
首次登陆需要注册
注册用户名:abcd
注册密码:987654
已经加载成功1学生信息
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:0
[admin@localhost cfile]$ ./file
Login...
请输入用户名:abcd
请输入密码:123456
error login
[admin@localhost cfile]$ ./file
Login...
请输入用户名:abcd
请输入密码:987654
已经加载成功1学生信息
查看功能列表:
1.查看所有学生信息
2.录入学生信息
3.按成绩排序
4.查询学生成绩
5.删除学生信息
0.退出
请选择功能:0

整体程序请看文章《C语言进阶:学生信息管理系统的不断优化,大块程序拿去用》第3部分

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言进阶:文件操作,学生信息管理系统 的相关文章

  • C++【多线程】

    文章目录 一 什么是线程 二 创建线程 pthread create pthread join 三 线程退出 pthread exit pthread cancel 线程id pthread self 四 进程对于共享资源的访问 threa
  • 餐饮行业RPA之5大应用场景

    眼下 伴随着一系列风险因素 餐饮业的情况变得越来越困难 规模较小 财务状况较差的餐饮商户面临着极大的生存挑战 即使是有一定知名度和客源的大品牌餐饮加盟连锁店 也被逼到了墙角 近年来 餐饮业市场竞争激烈 而且同质化严重 即使没有疫情冲击 众多
  • 计算机恢复工具有哪些,电脑数据恢复软件选哪个?这三款恢复工具不容错过

    不论我们是使用电脑来编写学习论文 还是完成老师所留的专业作业 再或者是处理日常工作或者是紧急工作 我们都会在电脑上存储一些重要的文件 就算我们的电脑不是学习或工作所用的话 那么电脑上也会存储一些自己认为比较重要的文件的 即便我们将重要的文件
  • 基于SSM的图书管理系统

    一 系统简介 该项目是基于Java的SSM框架实现的图书管理系统 二 技术实现 1 后台框架 Spring SpringMVC MyBatis Ajax 2 UI界面 BootStrap 3 数据库 MySQL 5 7 4 加密 md5 随

随机推荐

  • java类库EthereumJ如何操作以太坊区块链

    在本文中 我们将看一下EthereumJ库 它允许我们使用Java与以太坊区块链进行交互 以太坊作为一种加密货币 利用去中心化 点对点 可编程区块链形式的数据库 以太坊虚拟机 EVM 通过连接不同的节点进行同步和操作 节点通过共识同步区块链
  • 哈夫曼树编码-C语言

    文章目录 哈夫曼树编码 1 实验目的 2 实验内容 3 实验工具 4 实验代码 5 实验结果 6 实验分析 7 资料 哈夫曼树编码 1 实验目的 了解二叉树的定义 理解二叉树的基本性质和存储结构 掌握哈夫曼树的构造 实现哈夫曼编码与译码算法
  • CVE-2017-16995————Ubuntu本地提权漏洞

    前言 近期看到了Ubuntu本地提权漏洞所以顺手演示一份 实践一波 漏洞描述 Ubuntu是一个以桌面应用为主的开源GNU Linux操作系统 基于Debian GNU Linux 近期有白帽子爆出 ubuntu 的最新版本 Ubuntu
  • 外置存储权限在哪打开_安卓手机外置sd卡权限怎么打开

    展开全部 在2 x的版本中 在manifest中配置的权限e68a843231313335323631343130323136353331333365643662android permission WRITE EXTERNAL STORA
  • bug: TypeError: Invalid attempt to spread non-iterable instance

    报错信息 分析 此类报错多为扩展运算符报错 问题代码 解决方式
  • Win11系统pin码忘记了怎么办?Win11忘记pin码解决方法

    Win11系统pin码忘记了怎么办 如果我们忘记了这个密码 那么就会导致无法进入到系统来使用电脑了 这个问题还是比较让人着急的 特别是需要开机进行电脑急用的用户 那么我们怎么去解决这个问题 接下来一起看看Win11忘记pin码解决方法 Wi
  • Windows时间戳的计算

    一 实验目的 掌握Windows中FileTime时间戳的手工解析方法 利用WinHex或X Ways等十六进制编辑器进行手工取证 把Windows中 MFT文件里记载的十六进制时间转化为 年月日时分秒 的可读时间 加深对于时间戳的理解 二
  • 日本核污水今日入海,这帮黑客怒了!

    自2011年东日本大地震以来 日本谋划已久的福岛核电站核污水排海计划已于8月24日下午起正式施行 预计排污周期长达30年 整个海洋及其生物都有可能遭受难不可逆的毁灭性打击 据现场媒体报道 经过17分钟的流淌 核污染水经由1公里的海底隧道流进
  • Web框架中的ORM框架

    Web框架中的ORM框架 在 Python 实现的 Web 框架中 通过 API 接口来访问后端的视图函数 视图函数对数据库中的数据进行处理然后返回给前端 在这个过程中 视图函数不是直接通过 SQL 来操作数据库 而是通过模型类的对象属性或
  • C语言练习题(15) 有如下代码,则 *(p[0]+1) 所代表的数组元素是( )(非常详细的讲解)

    1 有如下代码 则 p 0 1 所代表的数组元素是 int a 3 2 1 2 3 4 5 6 p 3 p 0 a 1 A a 0 1 B a 1 0 C a 1 1 D a 1 2 解析 C a 3 2 1 2 3 4 5 6 p 0 代
  • Ubuntu 16.04 gcc降级为4.8版本

    1 下载gcc g 4 8 sudo apt get install y gcc 4 8 sudo apt get install y g 4 8 2 链接gcc g 实现降级 cd usr bin sudo rm gcc sudo ln
  • 【算法与数据结构】236、LeetCode二叉树的最近公共祖先

    文章目录 一 题目 二 解法 三 完整代码 所有的LeetCode题解索引 可以看这篇文章 算法和数据结构 LeetCode题解 一 题目 二 解法 思路分析 根据定义 最近祖先节点需要遍历节点的左右子树 然后才能知道是否为最近祖先节点 那
  • localhost 已拒绝连接。

    Tomcat的localhost 8080拒绝访问 直接在tomcat的bin目录下双击startup bat 启动就好了 再访问localhost 8080就可以出来了
  • 坑爹公司大盘点 --- 转自拉钩

    那些年我们满怀憧憬迈入社会 却遭遇了理想与现实的碰撞 一起看看网上盘点的坑爹公司吧 遇到这样的公司真的是醉了 gt 转自拉钩 1 头衔公司 从入职第一天 就封你为大中华区销售总监 或者全球发行战略副总裁 全国市场委员会主席 然后没有手下 没
  • 如何有效保证Java代码单元测试覆盖率

    背景介绍 我们在实际项目开发过程中 不同level的童鞋由于专业技能的层次不同 导致在参与实际开发的业务代码中经常会出现各种bug 项目管理中好的pm或许会给充足的时间来让开发童鞋们定位修复这些bug 也有各种客观原因的PM不会在项目中预留
  • Spring Boot使用方法

    Spring Boot 七步走 1 勾选包 Spring Boot是自带TomCat的 创建Spring Boot工程文件 创建时需要更改资源下载地址 我选择阿里云的这个地址 而且Spring Boot不需要导包 只需要勾选需要的包 进入后
  • 深度学习基础:SVD奇异值分解及其意义【转】

    排版较好的一版 http shartoo github io SVD decomponent 上面的补充 奇异值的物理意义是什么 https www zhihu com question 22237507 answer 225371236
  • 使用 ELK 收集日志

    在当前分布式 微服务架构下 各个应用都部署在不同的服务器上 每个应用都在记录着自己重要或者不重要的日志信息 当我们要通过日志信息来排查错误时 可以根据出错应用在对应的机器上找报错相关的日志信息 但是 可能我们不具有相应服务器的访问权限 也可
  • 初学者入门:认识STM32单片机

    本教程含有较多专业词汇 大部分时候 不完全理解并不影响继续往下阅读 大家只需要了解大致的概念即可 当然 也鼓励大家多查百度和多问chatgpt 让自己学会的更多 什么是单片机 单片机 就是把中央处理器CPU 存储器 等计算机的功能部件 和定
  • C语言进阶:文件操作,学生信息管理系统

    文章目录 1 重定向 2 读文件和写文件 3 打开文件和关闭文件 4 综合大题 学生信息管理系统 5 二进制读文件和二进制写文件 6 文件定位 7 其他文件操作函数 8 系统再优化之用户登录与注册 1 重定向 重定向文件输出 把运行出来的内