我已经有一个学生信息文本
在这里我想理由文件打开方式的“w"方式进行删除某一个学生的信息,程序运行正常,但是文本内容并没有改变,
恳请指点指点我哪里错了,我已经很努力的调试了,但仍没有成效。
struct score
{
char id[8];
char name[11];
float gaoshu;
float lisan;
float luoji;
float gpa_gaoshu;
float gpa_lisan;
float gpa_luoji;
float gpa;
int rank;//排名
};
int cancle(int n)
{
struct score st[100];
struct score sub[99];
char id[8];
int find=0;
printf("请输入你要删除的学生学号:");
scanf("%s", &id);
FILE *fp;
fp=fopen("学生成绩管理2.txt","r");
if(fp==NULL)
{
printf("打开文件失败,请联系管理员\n");
getch();
return -1;
}
int c=0;
int index=0;//用于记录目标序号
while(!feof(fp))
{
fscanf(fp,"%s %s %f %f %f %f %f %f %f %d\n",st[c].id,st[c].name,st[c].gaoshu,st[c].lisan,st[c].luoji,st[c].gpa_gaoshu,st[c].gpa_lisan,st[c].gpa_luoji,st[c].gpa,st[c].rank);
if(strcmp(id,st[c].id)==0)
{
find = 1;
index = c;
}
c++;
}
fclose(fp);
if(n==0)
{
printf("已经没有学生成绩信息了,请按任意键返回\n");
getch();
showmenu();
return n;
}
if(find==0)
{
printf("没有该学生成绩信息,请按任意键返回\n");
getch();
showmenu();
return n;
}
else
{
int i;
//删除
for(i=0;i<c;i++)
{
if(i < index)
{
sub[i] = st[i];
}
else
{
sub[i] = st[i+1];
}
}
FILE *fp2;
fp2=fopen("学生成绩管理3.txt","w");
for(i=0;i<c-1;i++)
{
fprintf(fp2,"%s %s %f %f %f %f %f %f %f %d\n",sub[i].id,sub[i].name,sub[i].gaoshu,sub[i].lisan,sub[i].luoji,sub[i].gpa_gaoshu,sub[i].gpa_lisan,sub[i].gpa_luoji,sub[i].gpa,sub[i].rank);
}
fclose(fp2);
printf("学号为%s的学生成绩删除成功,请按任意键返回\n",id);
getch();
showmenu();
return n-1;
}
}
我的文本格式
1001 leo 100.00 100.00 100.00 64.00 64.00 64.00 192.00 0
1002 mary 99.00 99.00 99.00 63.90 63.90 63.90 191.70 0
1003 erin 60.00 60.00 60.00 0.00 0.00 0.00 0.00 0
1004 dennle 80.00 80.00 80.00 62.00 62.00 62.00 186.00 0
1005 kin 20.00 90.00 70.00 0.00 63.00 61.00 124.00 0
1006 bore 90.00 80.00 50.00 63.00 62.00 0.00 125.00 0
1007 wake 80.00 80.00 90.00 62.00 62.00 63.00 187.00 0
1008 cid 78.00 76.00 88.00 61.80 61.60 62.80 186.20 0
1009 cold 87.00 78.00 86.00 62.70 61.80 62.60 187.10 0
1010 summy 76.00 65.00 45.00 61.60 60.50 0.00 122.10 0
1011 hot 60.00 60.00 60.00 0.00 0.00 0.00 0.00 0
1012 cool 59.00 50.00 50.00 0.00 0.00 0.00 0.00 0
1013 hand 80.00 10.00 78.00 62.00 0.00 61.80 123.80 0
1014 rool 80.00 30.00 40.00 62.00 0.00 0.00 62.00 0
1015 roof 78.00 57.00 87.00 61.80 0.00 62.70 124.50 0
1016 wave 87.00 77.00 66.00 62.70 61.70 60.60 185.00 0
1017 like 99.00 77.00 77.00 63.90 61.70 61.70 187.30 0
1018 heud 28.00 88.00 76.00 0.00 62.80 61.60 124.40 0
1019 tghde 76.00 80.00 20.00 61.60 62.00 0.00 123.60 0
1020 yehdy 77.00 77.00 66.00 61.70 61.70 60.60 184.00 0
第34行,从文件读取学生信息那个fscanf()函数那里,在每个float结构成员前面加一个&取址符后可以读取到数据;
但在实际测试时发现,读取的浮点数还有误差,测试把这些成员由float类型改为double类型就读取数据正常了。
测试如下:
参考链接:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
struct score
{
char id[8];
char name[11];
// https://blog.csdn.net/lutx/article/details/5072043
// 下面的结构成员由float改为double,可以正常读取文件中的相应数据了。
double gaoshu;
double lisan;
double luoji;
double gpa_gaoshu;
double gpa_lisan;
double gpa_luoji;
double gpa;
int rank;//排名
};
void showmenu()
{
system("cls");
printf("*----------------------------------------------------*\n");
printf("* 欢迎使用**成绩管理系统 *\n");
printf("*----------------------------------------------------*\n");
printf("* 1: 录入成绩 *\n");
printf("* 2: 删除成绩 *\n");
printf("* 3: 修改成绩 *\n");
printf("* 4: 成绩查询 *\n");
printf("* 5: 成绩计算并排名 *\n");
printf("* 6: 显示成绩信息 *\n");
printf("* 0: 保存信息并退出系统 *\n");
printf("*----------------------------------------------------*\n");
printf("选择操作<0-6> \n");
return;
}
int cancle(int n)
{
struct score st[100];
struct score sub[99];
char id[8];
int find=0;
printf("请输入你要删除的学生学号:");
scanf("%s", id);
FILE *fp;
fp=fopen("学生成绩管理2.txt","r");
if(fp==NULL)
{
printf("打开文件失败,请联系管理员\n");
// https://blog.csdn.net/m0_65601072/article/details/124651590
getch();
return -1;
}
int c=0;
int index=0;//用于记录目标序号
while(!feof(fp))
{
//在每个float结构成员之前加个&取址符,以便顺利获取信息到结构成员
fscanf(fp,"%s %s %lf %lf %lf %lf %lf %lf %lf %d\n",st[c].id,st[c].name,
&st[c].gaoshu,&st[c].lisan,&st[c].luoji,&st[c].gpa_gaoshu,&st[c].gpa_lisan,&st[c].gpa_luoji,&st[c].gpa,&st[c].rank);
// printf("读取信息为;%s %s %lf %lf %lf %lf %lf %lf %lf %d\n",st[c].id,st[c].name,
// st[c].gaoshu,st[c].lisan,st[c].luoji,st[c].gpa_gaoshu,st[c].gpa_lisan,st[c].gpa_luoji,st[c].gpa,st[c].rank);
if(strcmp(id,st[c].id)==0)
{
find = 1;
index = c;
}
c++;
}
fclose(fp);
if(n==0)
{
printf("已经没有学生成绩信息了,请按任意键返回\n");
getch();
showmenu();
return n;
}
if(find==0)
{
printf("没有该学生成绩信息,请按任意键返回\n");
getch();
showmenu();
return n;
}
else
{
int i;
//删除
for(i=0;i<c;i++)
{
if(i < index)
{
sub[i] = st[i];
}
else
{
sub[i] = st[i+1];
}
}
FILE *fp2;
fp2=fopen("学生成绩管理3.txt","w");
for(i=0;i<c-1;i++)
{
fprintf(fp2,"%s %s %.2f %.2f %.2f %.2f %.2f %.2f %.2f %d\n",sub[i].id,sub[i].name,sub[i].gaoshu,sub[i].lisan,sub[i].luoji,sub[i].gpa_gaoshu,sub[i].gpa_lisan,sub[i].gpa_luoji,sub[i].gpa,sub[i].rank);
}
fclose(fp2);
printf("学号为%s的学生成绩删除成功,请按任意键返回\n",id);
getch();
showmenu();
return n-1;
}
}
int main(void){
cancle(20);
return 0;
}
学生成绩管理2.txt (测试数据文件):
1001 leo 100.00 100.00 100.00 64.00 64.00 64.00 192.00 0
1002 mary 99.00 99.00 99.00 63.90 63.90 63.90 191.70 0
1003 erin 60.00 60.00 60.00 0.00 0.00 0.00 0.00 0
1004 dennle 80.00 80.00 80.00 62.00 62.00 62.00 186.00 0
1005 kin 20.00 90.00 70.00 0.00 63.00 61.00 124.00 0
1006 bore 90.00 80.00 50.00 63.00 62.00 0.00 125.00 0
1007 wake 80.00 80.00 90.00 62.00 62.00 63.00 187.00 0
1008 cid 78.00 76.00 88.00 61.80 61.60 62.80 186.20 0
1009 cold 87.00 78.00 86.00 62.70 61.80 62.60 187.10 0
1010 summy 76.00 65.00 45.00 61.60 60.50 0.00 122.10 0
1011 hot 60.00 60.00 60.00 0.00 0.00 0.00 0.00 0
1012 cool 59.00 50.00 50.00 0.00 0.00 0.00 0.00 0
1013 hand 80.00 10.00 78.00 62.00 0.00 61.80 123.80 0
1014 rool 80.00 30.00 40.00 62.00 0.00 0.00 62.00 0
1015 roof 78.00 57.00 87.00 61.80 0.00 62.70 124.50 0
1016 wave 87.00 77.00 66.00 62.70 61.70 60.60 185.00 0
1017 like 99.00 77.00 77.00 63.90 61.70 61.70 187.30 0
1018 heud 28.00 88.00 76.00 0.00 62.80 61.60 124.40 0
1019 tghde 76.00 80.00 20.00 61.60 62.00 0.00 123.60 0
1020 yehdy 77.00 77.00 66.00 61.70 61.70 60.60 184.00 0
将里面的 scanf("%s", &id);修改为 scanf("%s", id);
非常感谢刚刚那位发消息的大哥
我可以提供一种解决方案,具体步骤如下:
FILE *fp = fopen("student.txt", "r+");
if (fp == NULL) {
printf("Failed to open file\n");
return 0;
}
int line_to_delete = 3;
char line[100];
int current_line = 1;
long int line_pos = ftell(fp); // 记录第一行的位置
while (fgets(line, 100, fp) != NULL) {
if (current_line == line_to_delete) {
line_pos = ftell(fp); // 如果是目标行,记录位置
break;
}
current_line++;
}
fseek(fp, line_pos, SEEK_SET); // 将文件指针移动到目标行
long int next_line_pos = ftell(fp);
while (fgets(line, 100, fp) != NULL) {
next_line_pos = ftell(fp);
fseek(fp, next_line_pos, SEEK_SET);
}
fseek(fp, line_pos, SEEK_SET); // 将文件指针移动到目标行
fwrite("\n", 1, 1, fp); // 覆盖当前行,写入空字符串
line_pos = ftell(fp);
fseek(fp, next_line_pos, SEEK_SET); // 将文件指针移动到下一行
while (fgets(line, 100, fp) != NULL) {
fwrite(line, strlen(line), 1, fp); // 将下一行数据向上移动一行
next_line_pos = ftell(fp);
fseek(fp, next_line_pos, SEEK_SET);
}
ftruncate(fileno(fp), line_pos); // 将文件截断到最后一行(覆盖目标行)
fclose(fp);
希望这个解决方案对你有所帮助。如果有任何问题,请随时联系我。