小甲鱼__带你学C带你飞___p59随机读写文件

p59 随机读写文件

需要移动文件内部的位置指针,再来进行读写。允许从文件的任意位置开始读写

位置指针,方便对文件的读写进行控制。系统为每个打开的文件设置了一个位置指示器,主要用于表示当前的读写位置。使用 ftell 函数获取位置指示器的值。

# include <stdio.h>
# include <stdlib.h>

int main(void){
   /* ftell 函数的返回值是一个long类型的值,因为文件可能会很长,
   用long类型的值存储当前的读写位置,从某种意义上来说,文件里面的位置
   是以数组的形式来存放,每一个位置有一个下标,ftell返回下标值*/
    FILE *fp;
    if((fp = fopen("hello.txt","w"))== NULL){
        printf("文件打开失败!\n");
        exit(EXIT_FAILURE);
    }
    printf("%ld\n",ftell(fp));
    // 打印当前的位置指示器的值
    fputc('F',fp);
    printf("%ld\n",ftell(fp));
    fputs("ishC\n",fp);
    printf("%ld\n",ftell(fp));
    
    rewind(fp);
    fputs("Hello",fp);
    // 此时插入数据会直接覆盖里面有的部分
    fclose(fp);
    return 0;
}

如何修改位置指示器的值? rewind函数,将位置指示器移动到文件头的位置。

随机读写:使用fseek函数

fseek函数用于设置文件流的位置指示器
# include <stdio.h>
int fseek(FILE *stream, long int offset, int whence);
offset: 指定从whence 参数的位置起偏移多少个字节
whence: 指定从开始偏移的位置,该参数可以使用下面任一值:
		SEEK_SET 文件头, SEEK_CUR 当前的读写位置 , SEEK_END 文件末尾
调用成功: 返回值 0
# include <stdio.h>
# include <stdlib.h>

# define N 4
struct Stu{
    char name[24];
    int num;
    float score;
}stu[N], sb;
int main(void){
    FILE *fp;
    int i;
    
    if( (fp = fopen("sorce.txt","wb")) == NULL){
        printf("打开文件失败!\n");
        exit(EXIT_FAILURE);
    }
    printf("请开始录入成绩 (格式: 姓名 学号 成绩)\n");
    for(i = 0; i < N;i++){
        scanf("%s %d %f",stu[i].name,&stu[i].num,&stu[i].score);
    }
    fwrite(stu,sizeof(struct Stu),N,fp);
    // 结构体用二进制写入函数
    fclose(fp);
    
    if( (fp = fopen("sorce.txt","rb")) == NULL){
        printf("打开文件失败!\n");
        exit(EXIT_FAILURE);
    }
    fseek(fp,sizeof(struct Stu),SEEK_SET);
    // 打印第二个,所以偏移一个结构体的位置
    fread(&sb,sizeof(struct Stu),1,fp);
    printf("%s(%d) 的成绩是: %.2f\n",sb.name,sb.number,sb.score);
    fclose(fp);
    return 0;
    // vi score.txt
}

不同操作系统对字符的存放不是完全一致的:

  • 对于以二进制模式打开的文件,fseek函数在某些操作系统可能不支持SEEK_END位置。
  • 对于以文本模式打开的文件,fseek函数的whence参数只能取 SEEK_SET 才是有意义的,并且传递给offset参数的值要么是0,要么是上一层对同个文件调用ftell函数获得的返回值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值