两种方法修改局部数据
一、借助新建文件
//已在内存中修改过单行数据后直接调用该函数
void RebuildFile(List a)//List为结构体指针,指针a指向已修改部分链表
{
int num1;
char name1[100];
double source;
FILE* p1 = fopen("...\\date.txt", "r");
FILE* p2 = fopen("...\\date2.txt", "w+");//新建date2.txt
while (fscanf(p1, "%d%s%lf", &num1, name1, &source) == 3)
{
if (strcmp(a->name, name1)) //未修改部分直接存入
fprintf(p2, "%d %s %.2lf\n", num1, name1, source);
else
fprintf(p2, "%d %s %.2lf\n", a->num, a->name, a->source);//修改后数据存入
}
fclose(p1);
fclose(p2);
remove("...\\date.txt");//删除date.txt文件
rename("...\\date2.txt", "...\\date.txt");//将date2.txt重命名为date.txt
}
但数据量很大时,单行改动就要重写整个文件,浪费很多计算资源。
二、文件指针定位覆盖
流程:
- 得到待修改的数据在文件中的位置
- 将文件内部指针定位到该位置
- 写入新数据到文件
1. 得到待修改的数据在文件中的位置
FILE* p = fopen("...\\date.txt", "r+");
long position;//后面用到
char name1[10];
printf("输入需要修改的姓名:");
scanf("%s",name1);
while (fscanf(p, "%d%s%lf", &num1, name1, &source) == 3)
{
if (strcmp(a->name, name1) == 0) //找到需要修改部分,此时读取文件指针位于该行末
break;
}
用于读取的文件指针无法用于写入
用long ftell( FILE *stream );
函数读取指针位置(相对文件首偏移字节数)
//接上
position = ftell(p);
position -= //待修改数据长度; 即定位到待修改数据前
2. 将文件内部指针定位到该位置
int fseek( FILE *stream, long offset, int origin )
函数
int origin | 说明 |
---|---|
SEEK_SET(0) | 从文件的开始处开始 |
SEEK_CUR(1) | 从当前位置开始 |
SEEK_END(2) | 从文件的结束处开始 |
fessk从orign处开始,向后偏移offset个字节数,offset < 0 即向前移动
fseek(p,position,1);//从当前位置开始
3. 写入新数据到文件
直接用fprintf
写入即可,会覆盖原文件,需考虑新数据长度小于原数据长度时,用空格覆盖。
来源:CSDN
作者:S_aitama
链接:https://blog.csdn.net/S_aitama/article/details/104590741