【文件】C语言

发布时间:2024年01月23日

1.文件的打开与关闭

①定义一个文件指针

②将fopen函数的返回值赋值给文件指针

③判断文件指针是否为空

④如果为空,使用perror输出错误信息

⑤使用fclose函数关闭文件

⑥将文件指针置为空,方便下次使用

#include <stdio.h>
int main()
{
    FILE* pf = fopen("test.txt", "r");//以只读的形式打开文件test.txt
        if (pf == NULL)//如果文件指针pf为空则输出错误信息
        {
            perror("fopen:");
        }
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空,方便后续使用
        return 0;
}

fopen("需要打开的文件主干和文件后缀(文件名和文件类型)","打开文件是为了做什么?");

1.1打开文件

fopen("test.txt","r")

“test.txt” - 要打开的文件

"r" - 以什么形式打开,r为只读

注意:①打开文件时,要保证文件存在,如果不存在会报错。②两个都需要加上双引号!!!

1.2关闭文件

fclose(fp)

fp - 要关闭的文件

表1-1 使用文件的方式

2.文件的顺序读写

注意:如果是以“w”形式打开的文件写入数据的话,每次写入时在打开文件的时候会将之前的数据清空。如果是要往文件内追加内容,在打开文件时需要以"a"的形式打开,这样就可以在文件的尾部继续写入数据。

2.1读取文件中的一个字符数据fgetc

需要读取时,在打开文件要以读取形式打开,即FILE* pf = fopen("test.txt", "r");

fgetc(pf);

pf - 要读取的文件

一次读取:fgetc(pf);

循环读取:

char cont = 0;

while ( (cont = fgetc(pf) ) != EOF)

{

printf("%c ", cont);

}

#include <stdio.h>
int main()
{    //read 读取 write写入
    FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
    if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
    {
        perror("fopen:");//输出错误信息
        return;
    }

    //读取一次文件中的字符数据
    int a = fgetc(pf);
    printf("%c", a);

    //循环读取文件中的字符数据
    char cont = 0;//定义变量
    while ( (cont = fgetc(pf) ) != EOF)//循环判断获取字符是否失败,失败的话会返回EOF,将获取到的内容赋值给变量cont
    {
        printf("%c ", cont);//如果正常获取,输出获取到的内容
    }

    fclose(pf);//关闭文件
    pf = NULL;//将文件指针置空
    return 0;
}

2.2向文件写入数据一个字符数据fputc

需要写入时,在打开文件要以写入形式打开,即FILE* pf = fopen("test.txt", "w");

fputc(ch,pf);

ch - 要写入的字符数据变量

pf - 要写入的文件

一次写入:

char ch = 'a';

fputc(ch, pf);

循环写入:

char ch = 0;

ch = getchar();

while (ch != '#')

{

fputc(ch, pf);

putchar(ch);

ch = getchar();

}

#include <stdio.h>
int main()
{    //read 读取 write写入
    FILE* pf = fopen("test.txt", "w");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
    
        //写入一次字符数据
        char c = 'a';
        fputc(c, pf);//将字符a写入pf所指向的文件中
    
        //循环写入字符数据,以#号结束
        char ch = 0;
        ch = getchar();//接收一个字符
        while (ch != '#')//判断是否等于结束符#
        {
            fputc(ch, pf);//写入一次字符数据
            putchar(ch);//输出到屏幕上
            ch = getchar();//继续接收字符数据直到为#
        }
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

2.3读取文件内的一行数据

需要读取时,在打开文件要以读取形式打开,即FILE* pf = fopen("test.txt", "r");

fgets(arr, 8, pf);

arr - 读取出来的数据存放的数组

8 - 需要读取的元素个数

pf - 需要读取的文件

注意:①读取个数为实际数据量n+1,因为其中包含了\0。例如文件数据为TianHua,如果是7的话只读取到TianHu+\0。②读取前要先保证文件内有数据可读。

#include <stdio.h>
int main()
{    //read 读取 write写入
    FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
    if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
    {
        perror("fopen:");//输出错误信息
        return;
    }

    //读取一行数据
    char arr[10] = { 0 };
    fgets(arr, 8, pf);
    printf("%s",arr);
    

    fclose(pf);//关闭文件
    pf = NULL;//将文件指针置空
    return 0;
}

2.4向文件写入一行数据fputs

需要写入时,在打开文件要以写入形式打开,即FILE* pf = fopen("test.txt", "w");

fputs("Tianhua\n",pf);

“TianHua” - 要写入的字符串数据

pf - 要写入的文件

#include <stdio.h>
int main()
{    //read 读取 write写入
    FILE* pf = fopen("test.txt", "w");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
    
        //写入一行数据
        fputs("TianHua\n", pf);
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

2.5格式化读取文件内容fscanf

需要读取时,在打开文件要以读取形式打开,即FILE* pf = fopen("test.txt", "r");

fscanf(pf, "%s %d %.2f", s.arr,(&s.age),(&s.score));

pf - 要读取的文件

pf之后参数与scanf格式一致

#include <stdio.h>
struct S 
{
        char arr[10];
        int age;
        float score;
};

int main()
{    
        struct S s = { "TianHua",20,90.9f };
        //read 读取 write写入
        FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
     
        //格式化读取数据
        fscanf(pf, "%s %d %.2f", s.arr,(&s.age),(&s.score));
        printf("%s %d %.2f\n", s.arr, s.age, s.score);
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

2.6格式化写入文件内容fprintf

需要写入时,在打开文件要以写入形式打开,即FILE* pf = fopen("test.txt", "w");

fprintf(pf,"%s %d %.2f",s.arr,s.age,s.score);

pf - 要写入的文件

pf之后参数与printf格式一致

#include <stdio.h>
struct S 
{
        char arr[10];
        int age;
        float score;
};

int main()
{    
        struct S s = { "TianHua",20,90.9f };
        //read 读取 write写入
        FILE* pf = fopen("test.txt", "w");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
    
        //格式化写入数据
        fprintf(pf,"%s %d %.2f",s.arr,s.age,s.score);
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

2.7二进制形式读取文件

以二进制形式读取时,在打开文件时要以二进制读取形式打开,即FILE* pf = fopen("test.txt", "rb");

fread(&s, sizeof(struct S), 1, pf);

&s - 读取的数据存放的地址

sizeof(struct S) - 要读取的元素的大小

1 - 读取的次数

pf - 读取的文件

#include <stdio.h>
struct S 
{
        char arr[10];
        int age;
        float score;
};

int main()
{    
        struct S s = { 0 };
        //rb 二进制形式读取 wb二进制形式写入
        FILE* pf = fopen("test.txt", "rb");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
    
        //二进制形式读取数据
        fread(&s, sizeof(struct S), 1, pf);
        printf("%s %d %.2f", s.arr, s.age, s.score);
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

2.8二进制形式写入文件

以二进制形式写入时,在打开文件时要以二进制写入形式打开,即FILE* pf = fopen("test.txt", "wb");

fwrite(&s, sizeof(struct S), 1, pf);

&s - 要写入的数据变量的地址

sizeof(struct S) - 要写入的元素的大小

1 - 写入的次数

pf - 写入的文件

#include <stdio.h>
struct S 
{
        char arr[10];
        int age;
        float score;
};

int main()
{    
        struct S s = { "TianHua",20,90.9f };
        //rb 二进制形式读取 wb二进制形式写入
        FILE* pf = fopen("test.txt", "wb");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
    
        //二进制形式写入数据
        fwrite(&s, sizeof(struct S), 1, pf);
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

表2-1 顺序读写函数表

3.文件的随机读写

3.1随机读写函数fseek

fseek(pf, 0, SEEK_SET);

pf - 操作的文件流

0 - 偏移量

SEEK_SET - 文件开始位置

SEEK_CUR - 文件位置标记当前位置

SEEK_END - 文件末尾

#include <stdio.h>
struct S 
{
        char arr[10];
        int age;
        float score;
};

int main()
{    
    struct S s = { 0 };
        FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
        //随机读取文件
        char ch = fgetc(pf);
    
        fseek(pf, 0, SEEK_SET);//文件开始
        ch = fgetc(pf);
        printf("%c\n", ch);
    
        fseek(pf, 1, SEEK_CUR);//文件位置标记当前位置
        ch = fgetc(pf);
        printf("%c\n", ch);
    
        fseek(pf, -3, SEEK_END);//文件末尾
        ch = fgetc(pf);
        printf("%c\n", ch);
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

运行结果

起始点

代码名字

用数字代表

文件开始

SEEK_SET

0

文件位置标记当前位置

SEEK_CUR

1

文件末尾

SEEK_END

2

表3-1 fseek函数中的“起始点”表示方法

3.2当前指针相对于起始位置的偏移量函数ftell

ftell(pf);

pf - 操作的文件流

#include <stdio.h>
struct S 
{
    char arr[10];
    int age;
    float score;
};

int main()
{    
    struct S s = { 0 };
    FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
    if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
    {
        perror("fopen:");//输出错误信息
        return;
    }
    //随机读取文件
    char ch = fgetc(pf);

    fseek(pf, 0, SEEK_SET);//文件开始位置
    ch = fgetc(pf);
    printf("%c\n", ch);

    
    printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
    rewind(pf);//将文件指针位置归位到起始位置
    printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量

    fseek(pf, 1, SEEK_CUR);//文件位置标记当前位置
    ch = fgetc(pf);
    printf("%c\n", ch);

    
    printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
    rewind(pf);//将文件指针位置归位到起始位置
    printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量


    fclose(pf);//关闭文件
    pf = NULL;//将文件指针置空
    return 0;
}

运行结果

3.3将当前文件指针归位为起始位置函数rewind

rewind(pf);

pf - 要操作的文件流

#include <stdio.h>
struct S 
{
        char arr[10];
        int age;
        float score;
};

int main()
{    
        struct S s = { 0 };
        FILE* pf = fopen("test.txt", "r");//定义文件指针,将文件指针指向打开的文件
        if (pf == NULL)//判断打开文件是否失败,如果失败指针返回为空
        {
            perror("fopen:");//输出错误信息
            return;
        }
        //随机读取文件
        char ch = fgetc(pf);
    
        fseek(pf, 0, SEEK_SET);//文件开始位置
        ch = fgetc(pf);
        printf("%c\n", ch);
    
        
        printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
        rewind(pf);//将文件指针位置归位到起始位置
        printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
    
        fseek(pf, 1, SEEK_CUR);//文件位置标记当前位置
        ch = fgetc(pf);
        printf("%c\n", ch);
    
        
        printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
        rewind(pf);//将文件指针位置归位到起始位置
        printf("当前文件指针偏移量为:%d\n", ftell(pf));//找到当前的文件指针相对于起始位置的偏移量
    
    
        fclose(pf);//关闭文件
        pf = NULL;//将文件指针置空
        return 0;
}

运行结果

4.为什么使用文件

直接运行程序是在内存上,数据不存储,用完就丢。使用文件把数据放到硬盘/磁盘就可以持久化。

5.什么是文件

磁盘上的文件是文件,在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。

5.1程序文件

包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。

5.2数据文件

数据文件有两类:ASCII文件(文本文件)二进制文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

一个数据在内存中是怎么存储的呢?

字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。

如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。

5.2.1ASCII文件(文本文件)

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件

5.2.2二进制文件

数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件

6.文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。和键盘缓冲区是一个道理的。

?

文章来源:https://blog.csdn.net/Tianhuadkc/article/details/135759006
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。