c语言如何从文件中读取信息到链表 您所在的位置:网站首页 fscanf循环 c语言如何从文件中读取信息到链表

c语言如何从文件中读取信息到链表

2023-08-15 03:39| 来源: 网络整理| 查看: 265

写这篇博客原因:

c程序课设 忙的头昏脑涨,看了大量的博客。但是发现,文件操作这方面很少有简单易懂实用的博客。我作为大一新生,把自己学到的一点点文件操作功能分享一下。希望可以加快学者们的步伐。 源代码在最下面! 已更新代码 新加说明书界面 修改信息功能及界面超帅 再次更新代码 新加了智能化功能 **1.读取文件信息到链表。 省去了手动输入的麻烦

老师力推这个功能!!

2.删除读入的全部信息。** 与基本功能配套使用 很完美

喔对了。系统可以使用特殊符号 记得自己尝试一下 在这里插入图片描述

代码可以根据函数名自取

还没学如何快速到达自己感兴趣的模块 不好意思。。。。 1.数据储存到文件 2.如何按格式读取文件想要的信息,常用于密码登录。

进入正题:

先看效果 是不是你们想要的。先看效果 是不是你们想要的。 这是写出后的两个文件对比; 左边是录入原数据,右边是排名计算后写入的数据。

上代码(可以先看下代码下方的分部解析)

1.原始数据储存 功能函数

void Save_massage1(struct stu*p_Head) { struct stu* p = p_Head; char s[100] = { "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 \n" }; char s2[100] = { "-----------------------------------------------------------------------------------\n" }; //打开文件 //定义一个文件指针p_file FILE* p_File;//这里是文件结构体声明 这里不展开。没有它不行 p_File = fopen("playerOriginal.dat.txt", "w"); if (p_File == NULL) { printf("打开文件失败\n"); return 0; //exit (0); } else //写入数据 { fprintf(p_File, "%s", s); fprintf(p_File, "%s", s2); while (p!= NULL) { int i = 0; fprintf(p_File, "%s\t", p->name); fprintf(p_File, "%d\t", p->rank); for (i = 0; i //打开文件 //定义一个文件指针p_file FILE* p_File; //这里是文件结构体声明 这里不展开。没有它不行 p_File = fopen("playerGrade.dat.txt", "w"); if (p_File == NULL) { printf("打开文件失败\n"); return 0; //exit (0); } else printf("本地保存成功\n"); struct stu* p = p_Head; char s[100] = { "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 average\n" }; char s2[100] = { "---------------------------------------------------------------------------------------------\n" }; //写入数据 fprintf(p_File, "%s", s); fprintf(p_File, "%s", s2); while (p != NULL) { int i = 0; fprintf(p_File, "%s\t", p->name); fprintf(p_File, "%d\t", p->rank); for (i = 0; i int i; struct Stu p_temp = { 0," ",0,0 }; //这里用的是vs2019 如果代码不在一个文件内 需要进行结构体定义; FILE* fp; char filename[30] = { "playerGrade.dat.txt" };//z这里是要读取的文件名 if ((fp = fopen(filename, "r+")) == NULL)//判断文件是否打开失败 { printf("can not open!\npress any key to continue\n"); getchar(); exit(0); } else { int j; //对文件读写操作 行 列。 for 循环 行读取 便读取边赋值结构体变量。 fseek(fp,173, 0);//跳过开头 for (i = 0; i Menu_player();//这里是我自定义的界面函数 可忽略 system("pause");//忽略 //这个是界面设置 前面一半在主函数 读者自己设计界面美化 //下面的printf 内的** 星号 空格都是为了界面美化搞得 可以不要 printf("** 姓名%s\t", p_temp.name); printf("排名%d\t", p_temp.rank); //十个评委的分数可不要 /*for (j = 0; j < 10; j++) { printf("%6.2f ", p_temp.score[j]); }*/ printf("最终成绩:%6.2f **\n", p_temp.aver); printf("*************************************************\n"); printf("************--欢迎下年再来--*********************\n"); break; } } //文件查找 相同姓名 然后输出那一行内容 if (strcmp(p_temp.name, name) != 0) printf("输入信息错误,或者未录入。"); system("pause"); system("cls"); fclose(fp); }

问题来了: 1.文件内容开头是我们的格式 并不需要读取,那么怎么跳过? 在这里插入图片描述 这里利用fseek库函数 fseek(fp,173, 0);//跳过开头格式 fseek(文件指针,跳过的字节数,从哪里开始跳) 文件指针 经过上面两个信息储存大家应该了解了, 那么字节数怎么把控?一个一个数?其中’+’’-'代表往前往后跳。 我们用的是+ 往哪里跳,0 开头,1当前所在位置 这个目前还没用过,2从尾开始跳 我们用的是0 开头

下面就看怎么获得格式数据的字节数了 ,如何刚刚好跳过没用信息? 看操作

在这里插入图片描述 在这里插入图片描述 都秒懂是吧??? 不过要注意 这里我读取的是我的第二个文件 两个文件的格式不一样哦在这里插入图片描述 在这里插入图片描述 多一个average 2.如何正确读取文件数据到变量; 我这里写入的时候就是用的链表数据写入的 所以我定义了一个结构体 类型 不含 next指针 在这里插入图片描述 用第二种;

看代码:

呃,,,,自己往上面翻。

下面将我的整个代码给出来吧。 我是用vs2019 写的 忽略scanf警告 如何忽略? 看图 两种方法 在这里插入图片描述 右击源文件 点属性

在这里插入图片描述 在这里插入图片描述

在预处理器定义内输入 _CRT_SECURE_NO_WARNINGS

每建立一个新文件都需要这个操作

第二种方法; 在代码前头加 #define _CRT_SECURE_NO_WARNING

例如: 在这里插入图片描述

在这里插入图片描述

如果有不足的地方或者可以优化的地方 还望指出 每个代码人 都渴望提升啊。

评分管理系统要求如图: 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

#include #include #include int i_count=0; int menu1=1, menu2=1;//菜单选项 #define N 10 //最大节点数 可修改 //说明书界面 void Menu_help() { printf("*****************比赛评分系统灿哥版520.v*******************\n"); printf("** **\n"); printf("**_____________________--欢迎使用--_____________________ **\n"); printf("** **\n"); printf("** **\n"); printf("***************《详细说明书.爱心6.0tv版》******************\n"); printf("**-------------------------------------------------------**\n"); printf("** **\n"); printf("**一、姓名确定身份!决定你的权限 **\n"); printf("** **\n"); printf("**二、按照功能菜单进行键入对应数字! **\n"); printf("** **\n"); printf("**三、选手只能查取自己对应的最终成绩! **\n"); printf("** **\n"); printf("**四、管理员切记按正常顺序操作,记得保存录入的信息到文件!**\n"); printf("** **\n"); printf("**--------------------【任意键返回】---------------------**\n"); printf("***********************************************************\n"); } //修改信息时的界面 void Menu_moidfy() { printf("*****--修改系统--*****\n"); printf("**------------------**\n"); printf("** 1.修改序号 **\n"); printf("** 2.修改姓名 **\n"); printf("** 3.修改成绩 **\n"); printf("** 4.退出菜单 **\n"); printf("**------------------**\n"); printf("***************************\n"); printf("*|-----------------------**\n"); printf("*| **\n"); } //管理员界面 void Menu_gaver() { printf("\n****************╭ ||管理版||╮********************\n"); printf("*\t 欢迎使用比赛评分系统 \t\t*\n"); printf("*\t\t ╭ (`ε`)╮\t\t\t*\n"); printf("*************************************************\n"); printf("*-----------------------------------------------*\n"); printf("*\t\t 1.智能化功能\t\t\t*\n"); printf("*\t\t 2.手动功能\t\t\t*\n"); printf("*\t\t 0.退出系统\t\t\t*\n"); printf("*************************************************\n"); printf("||→_→ 请输入功能菜单序号:"); } //选手界面 void Menu_player() { printf("\n*******************选手版************************\n"); printf("*\t\t欢迎使用\t\t\t*\n"); printf("*\t\t祝您好运!\t\t\t*\n"); printf("*************************************************\n"); printf("*************************************************\n"); printf("*************************************************\n"); printf("*\t\t一键查取成绩\t\t\t*\n"); printf("*************************************************\n"); printf("*************************************************\n"); } void Menu_intellent() { printf("\n****************╭ ||管理版||╮********************\n"); printf("*\t 欢迎使用比赛评分系统 \t\t*\n"); printf("*\t\t ⊙﹏⊙\t\t\t*\n"); printf("*************************************************\n"); printf("******************智能化功能*********************\n"); printf("*-----------------------------------------------*\n"); printf("*\t\t1.智能读取文件信息\t\t*\n");//后期加入 printf("*\t\t2.批量删除选手信息\t\t*\n");//后期加入 printf("*\t\t0.返回上一级\t\t\t*\n"); printf("*************************************************\n"); printf("||-->请输入功能菜单序号:"); } void Menu_hand() { printf("\n****************╭ ||管理版||╮********************\n"); printf("*\t 欢迎使用比赛评分系统 \t\t*\n"); printf("*\t\t T^T\t\t\t*\n"); printf("*************************************************\n"); //printf("* *\n"); printf("*******************人工功能**********************\n"); printf("*-----------------------------------------------*\n"); printf("*\t\t1.录入选手信息\t\t\t*\n"); printf("*\t\t2.删除退赛选手信息\t\t*\n"); printf("*\t\t3.插入新选手信息\t\t*\n"); printf("*\t\t4.修改信息\t\t\t*\n"); //后期新加入的 printf("*\t\t5.保存数据\t\t\t*\n"); printf("*\t\t6.自动排名保存\t\t\t*\n"); printf("*\t\t7.输出全部信息\t\t\t*\n"); printf("*\t\t8.输入姓名查信息\t\t*\n"); printf("*\t\t9.详细说明书\t\t\t*\n"); printf("*\t\t0.退出系统\t\t\t*\n"); printf("*************************************************\n"); printf("||-->请输入功能菜单序号:"); } struct stu { int rank; char name[20]; float score[10]; float aver; struct stu* p_next; }; struct Stu { int rank; char name[20]; float score[10]; float aver; }; struct stu* p_end = NULL;//全局变量 尾指针 struct stu* p_Head = NULL;//头结点 void creat(void){ int i;//I表示输入的选手序号 后期排序用 排名 /*struct stu* p_head = NULL;*/ struct stu* p; p = (struct stu*)malloc(sizeof(struct stu));//开辟结构体变量内存 printf("输入的第几个选手:\n"); scanf("%d",&p->rank ); while (p->rank != i_count + 1) { printf("输入序号不对!\n"); printf("请重新输入!\n"); scanf("%d", &p->rank); } printf("输入选手姓名:\n"); scanf("%s", &p->name); for (i = 0; i i_count++; if (i_count == 1) { p->p_next = p_Head;//此时head为null 使新节点下一个指向null p_Head = p; //头指针赋值 p_end = p; } else { p->p_next = NULL; //与第一个节点相同 需要将新节点next 指向null p_end->p_next = p;//将新旧节点搭建关系 p_end = p;//尾指针更新 } p = (struct stu*)malloc(sizeof(struct stu)); printf("输入的第几个选手:\n"); printf("输入0结束\n"); scanf("%d", &p->rank); //输入0 结束 if (0==p->rank) break; while (p->rank != i_count+1) { printf("输入序号不对!\n"); printf("请重新输入!\n"); scanf("%d", &p->rank); } printf("输入选手姓名:\n"); scanf("%s", &p->name); for (i = 0; i //在程序未关闭前,可以改original 但绝对不改grade文件内的 实际安全问题 struct stu* p = p_Head; char name[20]; int num; int i; printf("请输入要要修改的学生的姓名:\n"); scanf("%s", &name); printf("请输入要要修改的学生的序号:\n"); //序号不会错 或者很少用 这个当娱乐 scanf("%d", &num); //修改的话只能修改重复型错误 不要往后修改 getchar(); for (i = 0; i while (1) { system("cls"); Menu_moidfy(); printf("*|请选择菜单编号:"); char ch = getchar(); switch (ch) { case '1': printf("*|请输入新的序号:"); scanf("%d", &p->rank); printf("*|修改序号成功!\n"); system("pause"); getchar(); system("cls"); break; case '2': printf("*|请输入新的姓名:"); scanf("%s", &p->name); printf("*|修改姓名成功!\n"); system("pause"); getchar(); system("cls"); break; case '3': printf("*|请输入新的成绩:\n"); for (i = 0; i p = p->p_next; } } if (p== NULL) { printf("未识别该选手!!!\n"); } } //用遍历链表 search 解决了报告要求的输出三个内容 排名 分数 struct stu* Search_name(struct stu* p_Head,char name[]) { struct stu* p = p_Head; while (p!= NULL) { if (strcmp(name, p->name)==0) { break; } else { p = p->p_next; } } return p; } void Sort_aver(struct stu* p_Head) { int i, j, I, J, T; float sum, temp; struct stu* p = p_Head; for (i = 0; i T = I; temp = p->score[I]; for (J = I + 1; J temp = p->score[J];//这里 temp 已经存了j 对应的最小值了 T = J; } } if (T != I) { p->score[T] = p->score[I]; p->score[I] = temp; } } for (j = 1, sum = 0; j float temp; int t,i,j; struct stu* p = p_Head; struct stu Temp; struct stu* p1 = NULL;//p1 p2 要交换的两个节点 struct stu* p2 = NULL; p1 = p_Head; //选择排序思想排序 节点 对成员进行排名 for (i = 1; i if (tempaver) { t = j; p2 = p;//储存要交换的节点地址; temp = p->aver; } p = p->p_next; } if (t != i) { //p1->rank = ; //p2->rank = i; //排名交换 p2->rank = i; p1->rank = t; //数据交换 Temp=*p1; //交换节点 memcpy(p1, p2, 68); memcpy(p2, &Temp, 68); } p1 = p1->p_next; p = p1; } } struct stu* Delete(struct stu* p_Head, int index) //pHead表示头结点,iIndex表示要删除的结点下标 { int i; int temp2 = 1;//同下 专门解决连续删除两次头节点 int temp = i_count;//专门解决 间断性删除两次尾节点造成的问题 struct stu* p_temp; /*临时指针*/ struct stu* p_pre; /*表示要删除结点前的结点*/ p_pre = p_temp = p_Head; //得到头结点 //删除头结点 if (index == temp2) { p_temp = p_Head->p_next; p_Head = NULL; free(p_Head); //释放掉要删除结点的内存空间 i_count--; temp2++; return p_temp; } //删除尾结点 else if (index ==temp) { for (i = 1; i for (i = 1; i struct stu* p = p_Head; char s[100] = { "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 \n" }; char s2[100] = { "-----------------------------------------------------------------------------------\n" }; //打开文件 FILE* p_File; p_File = fopen("playerOriginal.dat.txt", "w"); if (p_File == NULL) { printf("打开文件失败\n"); return 0; //exit (0); } else //写入数据 { fprintf(p_File, "%s", s); fprintf(p_File, "%s", s2); while (p!= NULL) { int i = 0; fprintf(p_File, "%s\t", p->name); fprintf(p_File, "%d\t", p->rank); for (i = 0; i //打开文件 FILE* p_File; p_File = fopen("playerGrade.dat.txt", "w"); if (p_File == NULL) { printf("打开文件失败\n"); return 0; //exit (0); } else printf("本地保存成功\n"); struct stu* p = p_Head; char s[100] = { "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 average\n" }; char s2[100] = { "---------------------------------------------------------------------------------------------\n" }; //写入数据 fprintf(p_File, "%s", s); fprintf(p_File, "%s", s2); while (p != NULL) { int i = 0; fprintf(p_File, "%s\t", p->name); fprintf(p_File, "%d\t", p->rank); for (i = 0; i extern i_count; int i, j; struct stu* p = p_Head; printf("****************************************************************************************************\n"); printf("************************************《灿哥最帅》****************************************************\n"); printf(" **\n"); printf("共查询到%d个选手信息: **\n", i_count); printf("name\tNO.\taverge\tscore1 score2 score3 score4 score5 score6 score7 score8 score9 score10 **\n"); printf("--------------------------------------------------------------------------------------------- **\n"); for (i = 0; i printf("%6.2f,", p->score[j]); } printf(" **\n"); p = p->p_next; } printf(" **\n"); printf("***********************************《534宿舍赞助》**************************************************\n"); printf("****************************************************************************************************\n"); } //用文件判定学生还是管理 void Read_file(char name[]) { //char s[] = { "NAME NO. sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 average--------------------------------------------------------------------------------------------"};//后面用于读文件使用 /*struct Stu { int rank; char name[20]; float score[10]; float aver;*/ int i; struct Stu p_temp = { 0," ",0,0 }; FILE* fp; char filename[30] = { "playerGrade.dat.txt" }; if ((fp = fopen(filename, "r+")) == NULL)//判断文件是否打开失败 { printf("can not open!\npress any key to continue\n"); getchar(); exit(0); } else { int j; //对文件读写操作 行 列。 for 循环 行读取 便读取边赋值结构体变量。 fseek(fp,173, 0);//跳过开头 for (i = 0; i Menu_player(); system("pause"); printf("** 姓名%s\t", p_temp.name); printf("排名%d\t", p_temp.rank); //十个评委的分数可不要 /*for (j = 0; j < 10; j++) { printf("%6.2f ", p_temp.score[j]); }*/ printf("最终成绩:%6.2f **\n", p_temp.aver); printf("*************************************************\n"); printf("************--欢迎下年再来--*********************\n"); break; } } //文件查找 相同姓名 然后输出那一行内容 if (strcmp(p_temp.name, name) != 0) printf("输入信息错误,或者未录入。"); system("pause"); system("cls"); fclose(fp); } } void Refresh(struct stu* p_Head) { while (i_count--) { struct stu* p = p_Head; p = (struct stu*)malloc(sizeof(struct stu));//开辟结构体变量内存 p_Head = p->p_next; free(p); } i_count = 0; } void Read_massage_file(int num) { struct stu* p; p = (struct stu*)malloc(sizeof(struct stu));//开辟结构体变量内存 FILE* fp; char filename[30]; //= { "2.txt" };//可以键入 printf("请输入要读取的文件:"); scanf("%s", &filename); getchar(); if ((fp = fopen(filename, "r+")) == NULL)//判断文件是否打开失败 { printf("打开失败!\n"); getchar(); system("pause"); exit(0); } else { while (num--) { i_count++; if (i_count == 1) { p->p_next = NULL;//此时head为null 使新节点下一个指向null p_Head = p; //头指针赋值 p_end = p; } else { p->p_next = NULL; //与第一个节点相同 需要将新节点next 指向null p_end->p_next = p;//将新旧节点搭建关系 p_end = p;//尾指针更新 } fscanf(fp, "%s %d %f %f %f %f %f %f %f %f %f %f \n", &p->name, &p->rank, &p->score[0], &p->score[1], &p->score[2], &p->score[3], &p->score[4], &p->score[5], &p->score[6], &p->score[7], &p->score[8], &p->score[9]); p = (struct stu*)malloc(sizeof(struct stu)); } free(p); } printf("读入成功!\n"); fclose(fp); } int main() { struct stu* p5 = NULL; int n = 1; char Name[20] = { "\0" }; char manage[20] = { "pipili" }; printf("************比赛评分系统灿哥版520.v***************\n"); printf("** **\n"); printf("**________________--欢迎使用--__________________**\n"); printf("** **\n"); printf("** **\n"); printf("** 请输入你的姓名:"); scanf("%s", &Name); getchar(); printf("** **\n"); printf("** **\n"); printf("** **\n"); printf("*************《本系统由一人承办》*****************\n"); char name_1[20] = { "\0" }; //分为选手和管理员 while (menu1) { if (strcmp(Name, manage) == 0) { Menu_gaver(); scanf("%d", &menu1); getchar(); system("cls"); switch (menu1) //两个界面 { case 0: { exit(0); } case 1://智能 { while (1) { Menu_intellent(); scanf("%d",&menu2); getchar(); switch (menu2) //两个功能 { case 0: { //getchar(); system("cls"); break; } case 1://读取文件 { system("cls"); int num = 0; printf("请输入要读取选手个数:\n"); scanf("%d", &num); Read_massage_file(num); system("pause"); getchar(); system("cls"); break; } case 2://全部清理 { getchar(); Refresh(p_Head); printf("清理完毕!"); /*system("pause"); getchar(); system("cls");*/ break; } default: { printf("请输入菜单上的可操作数字.\n"); break; } } if (menu2== 0) break; } break; } case 2://人工 { while (1) { Menu_hand(); //九大功能 scanf("%d", &menu2); getchar(); switch (menu2) { case 0: { system("cls"); break; } case 1: //插入 { getchar(); creat();//创建初期链表 及录入信xi printf("创建成功!\n"); system("pause"); getchar(); system("cls"); break; } case 2://删除 { getchar(); int index; printf("输入0返回!\n"); printf("输入要删除的序号(注意不是排名):"); scanf("%d", &index); getchar(); if (index > i_count) { printf("序号不存在!\n"); system("pause"); getchar(); system("cls"); break; } if (index == 0) { system("cls"); break; } p_Head = Delete(p_Head, index); printf("--已删除NO%d号选手!--\n", index); //提示信息 system("pause"); getchar(); system("cls"); break; } case 3://尾插 { getchar(); creat(); system("pause"); getchar(); system("cls"); break; } case 4://修改 { getchar(); Modify(); system("pause"); getchar(); system("cls"); break; } case 5://原数据保存 { getchar(); Save_massage1(p_Head); system("pause"); getchar(); system("cls"); break; } case 6://最终数据保存 { getchar(); Sort_aver(p_Head); Rank(p_Head); Save_massage2(p_Head); system("pause"); getchar(); system("cls"); break; } case 7://全部输出 { system("cls"); Print(p_Head); system("pause"); getchar(); system("cls"); break; } case 8://单独查找 { getchar(); printf("请输入要查询选手姓名:"); scanf("%s", &name_1); getchar(); p5 = Search_name(p_Head, name_1); if (p5 != NULL) { printf("姓名:%s\n", p5->name); printf("排名:%d\n", p5->rank); printf("最终成绩是:%6.2f\n", p5->aver); } else { printf("不存在该选手\n"); system("pause"); getchar(); system("cls"); break; } } case 9://说明书 { system("cls"); Menu_help(); system("pause"); getchar(); system("cls"); break; } default: { printf("请输入菜单上的可操作数字.\n"); break; } } if (menu2 == 0) break; } break; } default: { printf("请输入菜单上的可操作数字.\n"); break; } } } else { break; } } //用于判断 学生身份 Read_file(Name); return 0; }

简单的多文件操作 用dev的话 看这个 这个



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有