C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C语言文件读写操作

C语言实现文件读写操作的几种常用方法

作者:dlpmmk

C语言提供了一系列文件操作函数,使得我们可以通过程序对文件进行读写操作,本文主要介绍了C语言实现文件读写操作的几种常用方法,具有一定的参考价值,感兴趣的可以了解一下

一 、文件读写的常用函数

(1) 读写文本文件:

读文本文件 :一般都使用 getc 、fgets 、fscanf 函数

使用getc读文件

#include <stdio.h>
int main()
{
    char a[20] = "a.txt";
    FILE *p = fopen(a,"r");
    if(p)
    {
        char c;
        while(1)
        {
            c = getc(p);
            if(c == EOF)
                break;
            printf("%c",c);
        }
        printf("\n");
        fclose(p);
    }
    else
    {
        printf("fail\n");
    }
    return 0;
}

使用fgets读文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("test.txt","r");
    if(p == NULL)
        return 0;
    char temp[1024];
    fgets(temp,sizeof(temp),p);
    while(!feof(p))
    {
        printf("%s",temp);
        fgets(temp,sizeof(temp),p);
    }
    fclose(p);
    return 0;
}

使用fscanf读文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("a.txt", "r");
    if(p == NULL)
    {
        printf("the file is close!");
        return 0;
    }
    char str1[200], str2[200], str3[200];
    int year;
    int status = fscanf(p, "%s %s %s %d", str1, str2, str3, &year); 
    while(!feof(p))
    {
        printf("%s %s %d %d status = %d\n", str1, str2, str3, year, status);
        status = fscanf(p, "%s %s %s %d", str1, str2, str3, &year);
    }
    fclose(p);
    return 0;
}

写文本文件 :一般都使用 putc 、 fputs、fprintf 函数

使用putc写文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("a.txt","w");
    if(p)
    {
        putc('h',p);
        fclose(p);
    }
    return 0;
}

使用fputs写文件

#include <stdio.h>
int main()
{
    FILE *p = fopen("abc.c","w");
    if(p)
    {
        fputs("#include <stdio.h>\nint main()\n{\nprintf(\"hello world\\n\");\nreturn 0;\n}",p);
        fclose(p);
    }
    return 0;
}

使用fprintf写文件

#include <stdio.h>
#include <string.h>
int main()
{
    FILE *p = fopen("a.txt","w");
    char buf[1024];
    fgets(buf, sizeof(buf), stdin);
    while(strcmp(buf,"exit\n") != 0)
    {
       fprintf(p, "%s", buf);
       fgets(buf, sizeof(buf), stdin); 
    }
    fclose(p);
    return 0;
}

(2) 读写二进制文件

读二进制文件: 使用fread 函数

代码:

#include <stdio.h>
void readFile()
{
    FILE *p = fopen("a.txt", "rb");
    char buf[20] = { 0 };
    int index = 0;
    while(1)
    {
        int res = fread(buf, 1, 5, p);
        printf("res = %d , ", res);
        if(feof(p))
            break;
        printf("buf = %s\n",buf);
        index++;
    }
    fclose(p);
    printf("%d\n", index);
}
int main()
{
    readFile();
    return 0;
}

写二进制文件: 使用fwrite 函数

代码

#include <stdio.h>
void writeFile()
{
    FILE *p = fopen("b.txt", "w");
    char buf = 'a';
    int i;
    for(i = 0; i < 10 ; i++)
    {
        fwrite(&buf, 1, 1, p);
        buf++;
    }
    fclose(p);
}
int main()
{
    writeFile();
    return 0;
}

二、文件读写的深层次的剖析

(1)操作系统与硬件储存

众所周知,我们的计算机操作系统都是由C语言写的,通过C语言协调物理内存与虚拟内存,操作系统想要向物理内存中写数据的时候,会费很大的力。

写数据到物理内存

当操作系统有一个字节的数据想要写入物理磁盘中,首先要经历一下几个步骤:

从磁盘中读数据

读数据的操作与写数据的操作正好相反,也是要经历总线请求与总线释放的过程。

总之,操作系统想要往磁盘中读写数据要经历很繁琐的过程。

(2)操作系统封装读写数据函数接口

每次操作系统与磁盘进行数据交互的时候,都会对CPU有一系列的操作指令,这些读写指令的合集就是读写函数,通过C语言实现这些读写函数再往外部抛出一系列的接口,就实现的读写数据的函数封装。

当用户想往磁盘中写入数据的时候只需要调用这些函数接口就行了。

然而这些函数都是针对最底层的数据存储操作,不利于计算机的操作性能提高,所以,有人就在这层函数的基础上再次进行封装,把性能更加好,更加优化的读写数据函数封装到C语言的标准库中。

在标准库中的读写数据函数,例如fwrite和fputs等等。它们不是每次写入一个字节数据就往物理磁盘中写入数据,而是利用函数在内存中开辟出一个固定大小的字节缓冲池,通过这个缓冲池,来实现数据的读与写。

(3)C语言中的数据缓冲池

C语言的所有读写函数,都会使用到数据缓冲池,无论是读数据操作,还是写数据操作,都会把数据临时存储到这里。

写数据

当我们使用C语言往文件中写入一个字节的数据的时候,会经历一下几个步骤:

从上面的步骤中可以看出我们的函数在执行到写入数据的操作的时候,数据并没有真正的写入到磁盘中,而是等到写入文件的操作结束的时候,才把数据缓冲池中的数据写入磁盘中。

同样的我们使用C语言读一个字节数据的时候,同样会经历一下步骤:

缓冲池工作原理

当知道我们的所有读写操作都要进入缓冲池时,我们同样要知道缓冲池的工作原理。

当缓冲池满了或者目标操作文件关闭的时候,缓冲池会自动刷新,写数据时,缓冲池的数据会进入物理磁盘;读数据时,缓冲池的数据会数据固定字节的数据进入输出终端。

总而言之,缓冲池仅仅是用户与物理磁盘之间数据交户的一个缓冲而已,不用想的太深奥。

三、使用函数刷新缓冲池

fflush函数:

函数作用:

刷新缓冲池

函数定义:

int fflush(FILE *P);

参数 返回值:

使用示例:

现有空文件a.txt

利用标准输入数据,在文件没有关闭的时候,查看文件内是否有写入的数据。

#include <stdio.h>
#include <string.h>
void write_file()
{
    FILE *p = fopen("a.txt", "w");
    char temp[100] = { 0 };
    while(1)
    {
        fgets(temp, sizeof(temp), stdin);
        if(strcmp(temp, "exit\n") == 0)
            break;
        fprintf(p, "%s", temp);
    }
    fclose(p);
}
int main()
{
    write_file();
    return 0;
}

运行结果:

输入中

[文件]$ gcc -o a fflush.c
[文件]$ a
hello

查看文件a.txt

可以看到文件为空,输入的文件现在正存储在缓冲池中。

输入exit退出输入,查看文件a

[文件]$ cat a.txt
hello

文件关闭,缓冲池中的数据写入磁盘。

现在我们创建一个函数使每输入一次都写入一次磁盘:

#include <stdio.h>
#include <string.h>
void write_file()
{
    FILE *p = fopen("a.txt", "w");
    char temp[100] = { 0 };
    while(1)
    {
        fgets(temp, sizeof(temp), stdin);
        if(strcmp(temp, "exit\n") == 0)
            break;
        fprintf(p, "%s", temp);
        fflush(p);
    }
    fclose(p);
}
int main()
{
    write_file();
    return 0;
}

运行结果:

输入中,查看a.txt

[文件]$ gcc -o a fflush.c
[文件]$ a
hello

再开启另一个终端查看文件 a.txt 状态:

[文件]$ cat a.txt
hello

输入结束,查看a.txt

[文件]$ a
hello
exit
[文件]$ cat a.txt
hello
[文件]$ 

可以看到使用fflush函数把缓冲池中的数据写入了磁盘。

四、总结

当我们在往磁盘中录入重要的非常重要的数据的时候,一定要使用fflush不断的刷新缓冲池,因为数据非常重要;但我们输入不重要的数据是一定要尽量减少使用fflush函数的次数,因为那样会让程序变得缓慢。

到此这篇关于C语言实现文件读写操作的几种常用方法的文章就介绍到这了,更多相关C语言 文件读写操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文