跳转至

文件读写常用函数总结


目录

  • C 语言文件读写常用函数总结
    • fopen 函数
    • fclose 函数
    • fseek 函数
    • fprintf 函数
    • fsanf 函数
    • feof 函数
    • fgetc 函数
    • fputc 函数
    • fwrite 函数
    • ftell 函数
    • rewind 函数

fopen 函数

  • 头文件:stdio.h
  • 原型: FILE fopen(const char filename, const char *mode);
  • 作用: 使用给定的模式 mode 打开 filename 所指向的文件。
  • 参数:
    • filename: 所需打开文件的文件名。
    • mode: 访问模式,如下表。
参数功能
r以只读方式打开文件,该文件必须存在。
r+以读 / 写方式打开文件,该文件必须存在。
rb+以读 / 写方式打开一个二进制文件,只允许读 / 写数据。
rt+以读 / 写方式打开一个文本文件,允许读和写。
w打开只写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。
w+打开可读 / 写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。
a以附加的方式打开只写文件。若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF 符保留)。
a+以附加方式打开可读 / 写的文件。若文件不存在,则会创建该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF 符不保留)。
wb以只写方式打开或新建一个二进制文件,只允许写数据。
wb+以读 / 写方式打开或新建一个二进制文件,允许读和写。
wt+以读 / 写方式打开或新建一个文本文件,允许读和写。
at+以读 / 写方式打开一个文本文件,允许读或在文本末追加数据。
ab+以读 / 写方式打开一个二进制文件,允许读或在文件末追加数据。
  • 返回值:
    文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回 NULL,并把错误代码存在 error 中。
  • 运用
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    fp = fopen("abc.txt", "r");/* 以只读的方式打开,"abc.txt"文件 */
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }
    fclose(fp); /* 关闭文件 */
    fp = NULL; /* 需要指向空,否则会指向原打开文件地址 */
    return 0;
}

fclose 函数

  • 头文件:stdio.h
  • 原型: int fclose(FILE *fp);
  • 作用: 把缓冲区内最后剩余的数据输出到内核缓冲区,并释放文件指针和有关的缓冲区。
  • 参数:
    • fp: 指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流
  • 返回值:如果流成功关闭,fclose 返回 0,否则返回 EOF(-1)。
  • 运用:
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int main()
{
    FILE *fp;
    fp = fopen("abc.txt", "r");/* 以只读的方式打开,"abc.txt"文件 */
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }
    fclose(fp); /* 关闭文件 */
    fp = NULL; /* 需要指向空,否则会指向原打开文件地址 */
    return 0;
}

fseek 函数

  • 头文件:stdio.h
  • 原型: int fseek(FILE *stream, long offset, int fromwhere);
  • 作用: 重定位流 (数据流 / 文件) 上的文件内部位置指针
    • 注意:文件指针指向文件 / 流。位置指针指向文件内部的字节位置,随着文件的读取会移动,文件指针如果不重新赋值将不会改变或指向别的文件。
  • 参数:
    • stream:文件指针
    • offset:偏移量,正数表示正向偏移,负数表示负向偏移
    • origin:设定从文件的哪里开始偏移, 可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
      • SEEK_SET: 文件开头
      • SEEK_CUR: 当前位置
      • SEEK_END: 文件结尾
        其中 SEEK_SET,SEEK_CUR 和 SEEK_END 对应数字依次为 0,1 和 2.
  • 返回值:成功,返回 0,失败返回非 0 值,并设置 error 的值,可以用 perror() 函数输出错误。
  • 运用
C
1
2
3
fseek(fp,100L,0);  //把fp指针移动到离文件开头100字节处;
    fseek(fp,100L,1);  //把fp指针移动到离文件当前位置100字节处;
    fseek(fp,-100L,2); //把fp指针退回到离文件结尾100字节处。

fprintf 函数

  • 头文件:stdio.h

  • 原型: int fprintf (FILE stream, const charformat, [argument])

  • 作用: 根据指定的格式 (format),向输出流(stream) 写入数据(argument)(和 printf 差不多,多了第一个参数,找到文件,printf 是输出东西到你的黑框框里面,这个是写到文件里面)

  • 注意:fprintf()会根据参数 format 字符串来转换并格式化数据,然后将结果输出到参数 stream 指定的文件中,直到出现字符串结束 (’\0’) 为止。

  • 返回值:若写入成功,返回值是写入文件中的字符个数(或字节个数),否则返回EOF(-1)。

  • 参数:

    • stream :指向 FILE 对象的指针,该 FILE 对象标识了流。
    • format : C 字符串,包含了要被写入到流 stream 中的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。
    • [argument]:附加参数列表
    • 运用
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
FILE *fp;
    int a = 10;
    fp = fopen("abc.txt", "r+");/* 以读/写的方式打开,"abc.txt"文件 */
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }
    fprintf(fp, "Hello world\n"); //向文件中写入Hello world.
    fprintf(fp, "%d", a); //向文件中写入a.
    fclose(fp); /* 关闭文件 */
    return 0;

fsanf 函数

  • 头文件:stdio.h

  • 原型: int fscanf(FILE stream, char format[,argument…]);

  • 作用: 从一个流中执行格式化输入,fscanf 遇到空格和换行时结束,注意空格时也结束。这与 fgets 有区别,fgets 遇到空格不结束。(和 sanf 类似不过多了第一个参数用来找文件,scanf 需要我们从键盘输入,fscanf 文件里面的内容相当于我们键盘输入的内容)

  • 返回值:整型,成功返回读入的参数的个数,失败返回 EOF(-1)。

  • 运用

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//文件abc.txt里面是 10
    FILE *fp;
    int ;
    fp = fopen("abc.txt", "r+");/* 以读/写的方式打开,"abc.txt"文件 */
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }
    fscanf(fp, "%d", &a);       //从文件中读出一个整型
    fclose(fp); /* 关闭文件 */
    return 0;

feof 函数

  • 头文件:stdio.h
  • 原型: int feof(FILE *stream);
  • 参数: 指向 FILE 对象的指针。
  • 作用: 判断是否到达文件末尾
  • 返回值:如果文件结束,则返回非 0 值,否则返回 0,
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
FILE *fp;
    fp = fopen("abc.txt", "r");//打开文件
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }
    if(feof(fp)) //判断是否到达文件末尾
        printf("We have reached the end of file\n");
      fclose(fp);
      return 0;

以下是对 feof函数 的详解

一、feof()是什么? feof()是检测流上的文件结束符的函数,如果文件结束,则返回非0值,否则返回0

一般在文件操作,中经常使用feof()判断文件是否结束。

二、feof()的经典错误 根据这个函数的定义,一般大家都是这样使用的,但是这样使用,文件中无论是否有内容,都会被判断为“文件不为空”。

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include<stdio.h>
int main(void)
{
    FILE *p;
    p = fopen("open.txt", "r");
    if (feof(p))
    {
        printf("文件为空。");
    }
    else
    {
        printf("文件不为空。");
    }
    return 0;
 }

三、feof()的原理

1.EOF EOF是一个计算机术语,为End Of File的缩写,在操作系统中表示资料源无更多的资料可读取。资料源通常称为档案或串流。通常在文本的最后存在此字符表示资料结束。

这个定义的意思是,文档的结尾都有一个隐藏字符”EOF”,当程序读取它的时候,就会知道文件已经到达结尾。通常使用while循环加EOF判断作为读取结束的标志。

EOF 的值通常为 -1,但它依系统有所不同。

2.feof() feof() 函数,并不是通过读取到文件的EOF来评判,这个文件是否为空。 对 feof() 来说,它的工作原理是,站在光标所在位置,向后看看还有没有字符。如果有,返回0;如果没有,返回非0。它并不会读取相关信息,只是查看光标后是否还有内容。

四、直接使用时的错误分析: 对于一个空文件来说,当程序打开它的时候,它的光标会停在文件的开头,但是由于文件里什么内容都没有存(但是EOF是存在的),即整个文件就存贮了一个EOF。当程序打开文件,并直接调用 feof() 时,这个函数就会站在光标的位置向后张望,结果就看见了EOF,然后就当然返回0了。

五、如何正确使用 既然我们明白了原理,那么如何正确的使用它呢?

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>
int main(void)
{
    FILE *p;
    p = fopen("open.txt", "r");
    getc(p);
    if (feof(p))
    {
        printf("文件为空。");
    }
    else
    {
        rewind(p);//将光标跳回到文件开头
        int a;
        fscanf(p,"%d",&a);
        printf("%d", a);
    }
    return 0;
 }

对于文件来说,无论是空文件,还是存有信息的文件,当文件被打开,光标处于默认的开头时,光标后都有信息,这时候调用 feof() 来查看光标后是否还有内容,就没意义。 所以我们需要从相同中找不同,先使用 getc() ,从文件中读取一个字符,让光标向后移动一个字符。这时空文件的光标就已经移动到EOF的后面,这时使用 feof() 就会返回1了。这才是 feof() 的正确用法。 但是要注意,一定要将光标回到文件的开头,因为之前判断文件是否为空时,将光标向前移动了一位,必须要将光标恢复到开头,这样才能保证文件的正常读取。

fgetc 函数

  • 头文件:stdio.h
  • 原型: int fgetc(FILE *stream)
  • 参数: 指向 FILE 对象的指针。
  • 作用: 从文件指针 stream 指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节。
  • 返回值:该字符对应的 ascll 码。如果读到文件末尾或者读取出错时返回 EOF
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
FILE *fp;
    int ch;
    fp = fopen("abc.txt", "r");//打开文件
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }
    ch = fgetc(fp); //将第一个字符读取出来,对应ascll赋值给ch
    fclose(fp);
    return 0;

fputc 函数

  • 头文件:stdio.h
  • 原型: int fputs(const char *s,FILE * stream)
  • 参数:
    • stream: 指向 FILE 对象的指针。
    • s: 写入文件的字符
  • 作用: 向文件中写入一个字符或一个字节的数据,文件内部写指针会自动后移一个字节的位置。
  • 返回值:返回写入文件的字符的 ASCII 码值,出错时,返回 EOF
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
FILE *fp;
    int ch;
    fp = fopen("abc.txt", "r");//打开文件
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }
    fputc(ch,fp);//将ch写入文件
    fclose(fp);
    return 0;

fwrite 函数

  • 头文件:stdio.h
  • 原型: size_t fwrite(const void ptr, size_t size, size_t nmemb, FILE stream)
  • 作用: 把 ptr 所指向的数组中的数据写入到给定流 stream 中。
  • 参数:
    • ptr: 这是指向要被写入的元素数组的指针,获取数据地址。
    • size: 这是要被写入的每个元素的大小,以字节为单位。
    • nmemb: 这是元素的个数,每个元素的大小为 size 字节。
    • stream: 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。
  • 返回值:如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误。
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
    FILE *fp;
    char msg[]="this is a test";
    char buf[20];

    fp = fopen("abc.txt", "r+");/* 以读/写的方式打开,"abc.txt"文件 */
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }

    fwrite(msg,1,strlen(msg)+1,fp); //将msg写入文件fp中  

    fseek(fp,0,SEEK_SET);//将fp指针移动到文件开头处

    fread(buf,1,strlen(msg)+1,fp);//从文件中读取出来strlen(msg)+1个字节东西,放入buf中

    printf("%s\n",buf);

    fclose(fp); /* 关闭文件 */
    fp = NULL; /* 需要指向空,否则会指向原打开文件地址 */

    system("pause");
    return 0;
}

fread 函数

  • 头文件:stdio.h

  • 原型: size_t fread( void buffer, size_t size, size_t count, FILE stream );

  • 作用: 从给定输入流 stream 读取最多 count 个对象到数组 buffer 中(相当于对每个对象调用 size 次 fgetc),把 buffer 当作 unsigned char 数组并顺序保存结果。(也就是从文件中读取内容)

  • 注意: fread 不区分文件尾和错误,因此调用者必须用 feof 和 ferror 才能判断发生了什么。

  • 参数:

    • buffer:
      指向要读取的数组中首个对象的指针
    • size
      每个对象的大小(单位是字节)
    • count
      要读取的对象个数
    • stream
      输入流
    • 返回值:返回成功读取的对象个数,若出现错误或到达文件末尾,则可能小于 count。
      若 size 或 count 为零,则 fread 返回零且不进行其他动作。
  • 运用

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
    FILE *fp;
    char msg[]="this is a test";
    char buf[20];

    fp = fopen("abc.txt", "r+");/* 以读/写的方式打开,"abc.txt"文件 */
    if (NULL == fp) /* 打开失败 */
    {
        printf("错误!");
        exit(1); /* 中止程序 */
    }

    fwrite(msg,1,strlen(msg)+1,fp); //将msg写入文件fp中  

    fseek(fp,0,SEEK_SET);//将fp指针移动到文件开头处

    fread(buf,1,strlen(msg)+1,fp);//从文件中读取出来strlen(msg)+1个字节东西,放入buf中

    printf("%s\n",buf);

    fclose(fp); /* 关闭文件 */
    fp = NULL; /* 需要指向空,否则会指向原打开文件地址 */

    system("pause");
    return 0;
}

ftell 函数

  • 头文件:stdio.h
  • 原型: long int ftell(FILE *stream)
  • 作用: C 库函数 long int ftell(FILE *stream) 返回给定流 stream 的当前文件位置。
  • 参数:

    • stream
      这是指向 FILE 对象的指针,该 FILE 对象标识了流。
    • 返回值:该函数返回位置标识符的当前值。如果发生错误,则返回 -1L,全局变量 errno 被设置为一个正值。
    • 运用
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

int main ()
{
   FILE *fp;
   int len;

   fp = fopen("file.txt", "r");
   if( fp == NULL ) 
   {
      perror ("打开文件错误");
      return(-1);
   }
   fseek(fp, 0, SEEK_END);

   len = ftell(fp);
   fclose(fp);

   printf("file.txt 的总大小 = %d 字节\n", len);

   return(0);
}

rewind 函数

  • 头文件:stdio.h
  • 原型: void rewind(FILE *stream)
  • 作用: C 库函数 void rewind(FILE *stream) 设置文件位置为给定流 stream 的文件的开头。
  • 参数:

    • stream
      这是指向 FILE 对象的指针,该 FILE 对象标识了流。
    • 返回值:该函数不返回任何值。
    • 运用
C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>

int main()
{
   char str[] = "This is runoob.com";
   FILE *fp;
   int ch;

   /* 首先让我们在文件中写入一些内容 */
   fp = fopen( "file.txt" , "w" );
   fwrite(str , 1 , sizeof(str) , fp );
   fclose(fp);

   fp = fopen( "file.txt" , "r" );
   while(1)
   {
      ch = fgetc(fp);
      if( feof(fp) )
      {
          break ;
      }
      printf("%c", ch);
   }
   rewind(fp);
   printf("\n");
   while(1)
   {
      ch = fgetc(fp);
      if( feof(fp) )
      {
          break ;
      }
      printf("%c", ch);

   }
   fclose(fp);

   return(0);
}