首页 > 编程笔记 > C语言笔记 阅读:3

C语言fseek()、ftell()和rewind()随机读写文件(附带实例)

对文件进行操作时,往往不需要从头开始,而是只操作指定内容。这时,就需要使用文件定位函数来实现对文件的随机读取。本节介绍 C语言提供的 3 个随机读写函数,分别四 fseek()、ftell() 和 rewind()。

C语言fseek()函数

fseek() 函数的作用是移动文件内部的位置指针。其一般形式如下:
fseek(文件类型指针,位移量,起始点);

表 1 起始点
起始点 表示符号 数字表示
文件首 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件尾 SEEK_END 2

例如,下面的语句表示将位置指针从当前位置向后退 20 个字节:
fseek(fp,-20L,1);
注意,fseek() 函数一般用于二进制文件。在文本文件中使用时,由于要进行转换,计算的位置会出现错误。

文件的随机读写在移动位置指针之后进行,即可用前面介绍的任一种读写函数进行读写。

【实例】快递员送快递。快递员通常会将收货人电话的后 4 位写到快递包裹上,作为取货号使用。编写程序,例如收货人电话是 123****8900,则输出取货号 8900。运行程序前,需要在 E 盘设置 goods.txt 文件,内容是收货人的手机号。代码如下:
#include<stdio.h>
#include<process.h>
int main()
{
    FILE *fp;
    char filename[30], str[50]; /* 定义两个字符型数组 */
    printf("请输入文件路径:\n");
    scanf("%s", filename); /* 输入文件名 */
    if((fp = fopen(filename, "wb")) == NULL) /* 判断文件是否打开失败 */
    {
        printf("不能打开文件!\n 请按任意键继续\n");
        getchar();
        exit(0);
    }
    printf("请输入字符串:\n");
    getchar();
    gets(str);
    fputs(str, fp);
    fclose(fp);
    if((fp = fopen(filename, "rb")) == NULL) /* 判断文件是否打开失败 */
    {
        printf("不能打开文件!\n 请按任意键继续\n");
        getchar();
        exit(0);
    }
    fseek(fp, 7L, 0);
    fgets(str, sizeof(str), fp);
    printf("\n取货号为:\n");
    puts(str);
    fclose(fp);
    return 0;
}
程序运行结果为:

请输入文件路径:
E:/demo.txt
请输入字符串:
123****8900
取货号为:
8900

其中,如下代码的含义是将文件指针指向距文件首 5 个字节的位置,也就是指向字符串中的第 6 个字符。
fseek(fp,5L,0);

C语言rewind()函数

rewind() 函数用于将位置指针重返文件开头,没有返回值。其一般形式如下:
void  rewind(文件类型指针)
【实例】给支付宝设置密码时,用户输入一次密码后,会提示再输入一次密码,模拟此场景。运行程序之前,需要在 E 盘设置 password.txt 文件,内容是设置的密码。
#include<stdio.h>
#include<process.h> // exit()
int main()
{
    FILE *fp;
    char ch, filename[50];
    printf("请输入文件路径:\n");
    scanf("%s", filename); /* 输入文件名 */
    if((fp = fopen(filename, "r")) == NULL) /* 以只读方式打开该文件 */
    {
        printf("不能打开文件\n");
        exit(0);
    }
    printf("\n输入密码:\n");
    ch = fgetc(fp);
    while(ch != EOF)
    {
        putchar(ch); /* 输出字符 */
        ch = fgetc(fp); /* 获取 fp 指向文件中的字符 */
    }
    rewind(fp); /* 指针指向文件开头 */
    printf("\n请再次输入密码:\n");
    ch = fgetc(fp);
    while(ch != EOF)
    {
        putchar(ch); /* 输出字符 */
        ch = fgetc(fp);
    }
    printf("\n");
    fclose(fp); /* 关闭文件 */
    return 0;
}
程序运行结果为:
请输入文件路径:
E:\password.txt

输入密码:
123456
请再次输入密码:
123456

来看一下下方的 6 行语句:
ch = fgetc(fp);
while(ch != EOF)
{
    putchar(ch); /* 输出字符 */
    ch = fgetc(fp);
}
通过以上语句,输出了第一个 123456,输出后文件指针移动到了文件尾部。使用 rewind() 函数再次将文件指针移到文件开始部分,因此当再次使用上面 6 行语句时,会输出第二个 123456。

C语言ftell()函数

ftell() 函数可得到流式文件中的当前位置,并使用相对于文件头的位移量表示。其一般形式如下:
long ftell(文件类型指针)
当 ftell 函数的返回值为 −1L 时,表示出错。

【实例】设置银行卡密码。银行卡密码只能是 6 位,设置 6 位,表示设置密码成功,否则失败。运行程序前,先在 E 盘设置 cipher.txt 文件,内容是银行卡密码。具体代码如下:
#include<stdio.h>
#include<process.h>
int main()
{
    FILE *fp;
    int n;
    char ch, filename[50]; /* 定义一个指向 FILE 类型结构体的指针变量 */
    printf("请输入文件路径:\n");
    scanf("%s", filename); /* 输入文件位置 */
    if((fp = fopen(filename, "r")) == NULL) /* 判断是否能打开文件 */
    {
        printf("不能打开此文件\n");
        exit(0);
    }
    printf("密码为:");
    ch = fgetc(fp); /* 读出一个字符 */
    while(ch != EOF)
    {
        putchar(ch);
        ch = fgetc(fp);
    }
    n = ftell(fp); /* 输出长度 */
    if(6 == n) /* 判断长度是否等于 6 */
        printf("\n设置密码成功\n");
    else
        printf("\n 设置密码失败\n");
    fclose(fp); /* 关闭文件 */
    return 0;
}
程序运行结果为:

请输入文件路径:
E:\cipher.txt
密码为:123456
设置密码成功


当需要将某个文件中的内容复制到另一个文件中时,可使用 fseek() 函数将文件指针指向文件尾,这样就可以将另一个文件中的内容逐个写到该文件中所有内容的后面,从而实现复制操作。

【实例】将两个文件内容合并到一起。在 E 盘创建两个文件 saying1、saying2,其中 saying1.txt 内容是“花儿凋谢不再开,”,saying2.txt 内容是“光阴一去不再来。”。编写程序,将文件 2 的内容复制到文件 1 中,代码如下:
#include<stdio.h>
#include<process.h>
main()
{
    FILE *fp1, *fp2;
    char ch, filename1[30], filename2[30];
    printf("请输入文件 1 的名字:\n");
    scanf("%s", filename1);
    printf("请输入文件 2 的名字:\n");
    scanf("%s", filename2);
    if((fp1 = fopen(filename1, "ab+")) == NULL)
    {
        printf("不能打开文件, 请按任意键继续\n");
        getchar();
        exit(0);
    }
    if((fp2 = fopen(filename2, "rb")) == NULL)
    {
        printf("不能打开文件, 请按任意键继续\n");
        getchar();
        exit(0);
    }
    fseek(fp1, 0L, 2);
    while((ch = fgetc(fp2)) != EOF)
    {
        fputc(ch, fp1);
    }
    fclose(fp1);
    fclose(fp2);
}
程序运行结果为:

请输入文件 1 的名字:
E:\saying1.txt
请输入文件 2 的名字:
E:\saying2.txt

程序执行结束后,saying1.txt 文件中的内容为:

花儿凋谢不再开,光阴一去不再来。

相关文章