【C 语言】文件操作 ( 学生管理系统 | 插入数据 | 查询数据 | 删除数据 )
文章目錄
- 一、學(xué)生管理系統(tǒng)
- 1、插入數(shù)據(jù)
- 2、查詢數(shù)據(jù)
- 3、刪除數(shù)據(jù)
- 二、完整代碼
一、學(xué)生管理系統(tǒng)
實(shí)現(xiàn)一個簡易學(xué)生管理系統(tǒng) , 驗(yàn)證文件操作 ;
1、插入數(shù)據(jù)
從命令行接收數(shù)據(jù) , 放入結(jié)構(gòu)體成員中 , 最后將結(jié)構(gòu)體數(shù)據(jù)寫出到內(nèi)存中 ;
/** 插入學(xué)生數(shù)據(jù)*/ int insert() {// 要寫入文件的結(jié)構(gòu)體struct student s1 = {0};// 打開要寫入的文件FILE *p = fopen("student.dat", "w");// 打開失敗直接退出if(p == NULL)return 0;while (1){// 提示輸入學(xué)生名字printf("input student's name:\n");// 阻塞等待命令行中用戶輸入學(xué)生名字scanf("%s", s1.name);// 如果用戶輸入 quit , 則退出循環(huán) , 保存文件if(strcmp(s1.name, "quit")==0)break;// 提示輸入某個學(xué)生的年齡printf("input %s's age:\n", s1.name);// 命令行阻塞等待用戶輸入學(xué)生年齡scanf("%d", &s1.age);// 將結(jié)構(gòu)體寫出到文件中fwrite(&s1, 1, sizeof (struct student), p);}// 關(guān)閉文件fclose(p);return 0; }2、查詢數(shù)據(jù)
從命令行中輸入要查詢的學(xué)生信息 , 如果查詢?nèi)繉W(xué)生信息 , 則傳入 “all” ;
循環(huán)從文件中讀取單個結(jié)構(gòu)體信息 , 逐個遍歷結(jié)構(gòu)體的 name 成員 , 查詢是否是要查詢的學(xué)生姓名 ; 如果是則打印該數(shù)據(jù) ;
/** 查詢學(xué)生數(shù)據(jù)*/ int query() {// 緩存信息用的結(jié)構(gòu)體struct student s = { 0 };// 要查詢的數(shù)組char name[30] = { 0 };// 提示輸入要查詢的學(xué)生名字printf("input student's name:");// name 數(shù)組接收控制臺輸入的字符串scanf("%s", name);// 打開文件FILE *p = fopen("student.dat", "r");// 文件打開失敗退出if (p == NULL)return 0;// 使用該變量記錄是否查詢到學(xué)生信息int status = 0;// 循環(huán)讀取 student 結(jié)構(gòu)體數(shù)據(jù)// 每次都可以讀取到一個學(xué)生數(shù)據(jù)// 判斷該數(shù)據(jù)是否是要查詢的學(xué)生數(shù)據(jù)while(1){// 從文件中讀取一個結(jié)構(gòu)體大小的數(shù)據(jù)fread(&s, 1, sizeof(struct student), p);// 判斷是否讀取到文件末尾, 注意 feof 必須在文件操作之后才能調(diào)用if (feof(p))break;// 如果學(xué)生名字是 all , 則打印所有學(xué)生信息if (strcmp(name, "all") == 0){// 打印學(xué)生信息printf("name=%s, age=%d\n", s.name, s.age);// 標(biāo)記信息找到status = 1;}else{// 對比本次讀取的學(xué)生信息是否是要查詢的信息if (strcmp(name, s.name) == 0){// 打印要查詢的學(xué)生信息printf("name=%s, age=%d\n", s.name, s.age);// 標(biāo)記信息找到status = 1;}}}// 關(guān)閉文件fclose(p);// 如果學(xué)生信息沒有找到, 打印提示信息if (status == 0)printf("student %s not found\n", name);return 0; }3、刪除數(shù)據(jù)
將所有的學(xué)生數(shù)據(jù)一次性全部讀取出來 ;
然后逐個遍歷 , 使用 結(jié)構(gòu)體指針 , 逐個遍歷上述全部數(shù)據(jù) ;
遍歷的同時 , 寫出數(shù)據(jù) , 如果學(xué)生的名字不是要刪除的名字 , 則重新寫出到文件中 , 否則數(shù)據(jù)丟棄 , 這樣就實(shí)現(xiàn)了數(shù)據(jù)刪除操作 ;
/** 刪除學(xué)生*/ int delete() {// 打開學(xué)生信息文件FILE *p = fopen("student.dat", "r");// 如果打開失敗, 退出if (p == NULL)return 0;// 獲取文件大小 , 將文件指針跳轉(zhuǎn)到文件結(jié)尾fseek(p, 0, SEEK_END);// 獲取文件指針位置 , 該位置就是文件大小int size = ftell(p);// 為學(xué)生類型結(jié)構(gòu)體分配堆內(nèi)存空間, 分配文件大小空間struct student *s = malloc(size);// 文件指針指向開始位置fseek(p, 0, SEEK_SET);// 將所有的文件數(shù)據(jù)讀取到堆內(nèi)存中fread(s, 1, size, p);// 關(guān)閉文件fclose(p);// 提示要刪除的學(xué)生名字printf("input delete student's name: ");// 獲取要刪除的學(xué)生名字char name[30] = { 0 };// 從命令行接收學(xué)生名字scanf("%s", name);// 統(tǒng)計(jì)文件中記錄了多少個學(xué)生信息int n = size / sizeof(struct student);//得到了多少記錄數(shù)// 循環(huán)控制變量int i;// 以寫的方式打開文件 , 本次寫入文件是覆蓋寫出文件p = fopen("student.dat", "w");// 循環(huán)遍歷結(jié)構(gòu)體數(shù)據(jù)for(i = 0; i < n; i++){// 學(xué)生數(shù)據(jù)不是要刪除的數(shù)據(jù), 才能寫出到文件中if (strcmp(s[i].name, name) != 0)// 寫出一條學(xué)生數(shù)據(jù)結(jié)構(gòu)體fwrite(&s[i], 1, sizeof(struct student), p);}// 關(guān)閉文件fclose(p);// 釋放內(nèi)存中的文件數(shù)據(jù)內(nèi)存free(s);return 0; }二、完整代碼
代碼示例 :
#include <stdio.h> #include <stdlib.h> #include <string.h>// 存儲學(xué)生姓名和年齡結(jié)構(gòu)體 struct student {char name[30]; // 姓名int age; // 年齡 };/** 插入學(xué)生數(shù)據(jù)*/ int insert() {// 要寫入文件的結(jié)構(gòu)體struct student s1 = {0};// 打開要寫入的文件FILE *p = fopen("student.dat", "w");// 打開失敗直接退出if(p == NULL)return 0;while (1){// 提示輸入學(xué)生名字printf("input student's name:\n");// 阻塞等待命令行中用戶輸入學(xué)生名字scanf("%s", s1.name);// 如果用戶輸入 quit , 則退出循環(huán) , 保存文件if(strcmp(s1.name, "quit")==0)break;// 提示輸入某個學(xué)生的年齡printf("input %s's age:\n", s1.name);// 命令行阻塞等待用戶輸入學(xué)生年齡scanf("%d", &s1.age);// 將結(jié)構(gòu)體寫出到文件中fwrite(&s1, 1, sizeof (struct student), p);}// 關(guān)閉文件fclose(p);return 0; }/** 查詢學(xué)生數(shù)據(jù)*/ int query() {// 緩存信息用的結(jié)構(gòu)體struct student s = { 0 };// 要查詢的數(shù)組char name[30] = { 0 };// 提示輸入要查詢的學(xué)生名字printf("input student's name:");// name 數(shù)組接收控制臺輸入的字符串scanf("%s", name);// 打開文件FILE *p = fopen("student.dat", "r");// 文件打開失敗退出if (p == NULL)return 0;// 使用該變量記錄是否查詢到學(xué)生信息int status = 0;// 循環(huán)讀取 student 結(jié)構(gòu)體數(shù)據(jù)// 每次都可以讀取到一個學(xué)生數(shù)據(jù)// 判斷該數(shù)據(jù)是否是要查詢的學(xué)生數(shù)據(jù)while(1){// 從文件中讀取一個結(jié)構(gòu)體大小的數(shù)據(jù)fread(&s, 1, sizeof(struct student), p);// 判斷是否讀取到文件末尾, 注意 feof 必須在文件操作之后才能調(diào)用if (feof(p))break;// 如果學(xué)生名字是 all , 則打印所有學(xué)生信息if (strcmp(name, "all") == 0){// 打印學(xué)生信息printf("name=%s, age=%d\n", s.name, s.age);// 標(biāo)記信息找到status = 1;}else{// 對比本次讀取的學(xué)生信息是否是要查詢的信息if (strcmp(name, s.name) == 0){// 打印要查詢的學(xué)生信息printf("name=%s, age=%d\n", s.name, s.age);// 標(biāo)記信息找到status = 1;}}}// 關(guān)閉文件fclose(p);// 如果學(xué)生信息沒有找到, 打印提示信息if (status == 0)printf("student %s not found\n", name);return 0; }/** 刪除學(xué)生*/ int delete() {// 打開學(xué)生信息文件FILE *p = fopen("student.dat", "r");// 如果打開失敗, 退出if (p == NULL)return 0;// 獲取文件大小 , 將文件指針跳轉(zhuǎn)到文件結(jié)尾fseek(p, 0, SEEK_END);// 獲取文件指針位置 , 該位置就是文件大小int size = ftell(p);// 為學(xué)生類型結(jié)構(gòu)體分配堆內(nèi)存空間, 分配文件大小空間struct student *s = malloc(size);// 文件指針指向開始位置fseek(p, 0, SEEK_SET);// 將所有的文件數(shù)據(jù)讀取到堆內(nèi)存中fread(s, 1, size, p);// 關(guān)閉文件fclose(p);// 提示要刪除的學(xué)生名字printf("input delete student's name: ");// 獲取要刪除的學(xué)生名字char name[30] = { 0 };// 從命令行接收學(xué)生名字scanf("%s", name);// 統(tǒng)計(jì)文件中記錄了多少個學(xué)生信息int n = size / sizeof(struct student);//得到了多少記錄數(shù)// 循環(huán)控制變量int i;// 以寫的方式打開文件 , 本次寫入文件是覆蓋寫出文件p = fopen("student.dat", "w");// 循環(huán)遍歷結(jié)構(gòu)體數(shù)據(jù)for(i = 0; i < n; i++){// 學(xué)生數(shù)據(jù)不是要刪除的數(shù)據(jù), 才能寫出到文件中if (strcmp(s[i].name, name) != 0)// 寫出一條學(xué)生數(shù)據(jù)結(jié)構(gòu)體fwrite(&s[i], 1, sizeof(struct student), p);}// 關(guān)閉文件fclose(p);// 釋放內(nèi)存中的文件數(shù)據(jù)內(nèi)存free(s);return 0; }/** 打印學(xué)生管理系統(tǒng)幫助信息*/ void printf_help() {printf("help info :\n");printf("i : insert student data\n");printf("q : query student data\n");printf("d : delete student data\n"); }/** 函數(shù)入口* 參數(shù) i 表示插入數(shù)據(jù)* 參數(shù) q 表示查詢數(shù)據(jù)* 參數(shù) d 表示刪除數(shù)據(jù)*/ int main(int argc, char **args) {// 判斷參數(shù)個數(shù)是否合法if (argc < 2){// 提示正確的參數(shù)信息printf_help();return 0;}// 插入數(shù)據(jù)if (strcmp(args[1], "i") == 0)insert();// 查詢數(shù)據(jù)if (strcmp(args[1], "q") == 0)query();// 刪除數(shù)據(jù)if (strcmp(args[1], "d") == 0)delete();return 0; }編譯程序 : 生成 student.exe 可執(zhí)行文件 ;
gcc main.c -o student
輸入錯誤參數(shù) : 如果輸入?yún)?shù)小于 2 個 , 則提示參數(shù)信息 ;
插入數(shù)據(jù) :
查詢數(shù)據(jù) :
刪除數(shù)據(jù) :
總結(jié)
以上是生活随笔為你收集整理的【C 语言】文件操作 ( 学生管理系统 | 插入数据 | 查询数据 | 删除数据 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【C 语言】文件操作 ( 学生管理系统
- 下一篇: 【Android 应用开发】Canvas