全栈开发知识库

5.文件读写(五)

文件处理函数

C语言库中有定义和实现了很多可以打开,读取,写入,搜索和关闭文件的函数。文件函数列表如下:

编号 函数名称 功能描述
1 fopen() 打开新的或现有的文件
2 fprintf() 将数据写入文件
3 fscanf() 从文件读取数据
4 fputc() 将一个字符写入文件
5 fgetc() 从文件读取一个字符
6 fclose() 关闭文件
7 fseek() 将文件指针设置为给定位置
8 fputw() 将一个整数写入到文件
9 fgetw() 从文件读取一个整数
10 ftell() 返回当前文件指针的位置
11 rewind() 将文件指针设置为文件的开头

打开文件:fopen()函数

fopen()函数用于打开文件,fopen()函数的语法如下:

FILE *fopen( const char * filename, const char * mode );

您可以在fopen()函数中使用以下模式之一。

模式 说明
r 以读取模式打开文本文件
w 以写入模式打开文本文件
a 以附加模式打开文本文件
r+ 以读写模式打开文本文件
w+ 以读写模式打开文本文件
a+ 以读写模式打开文本文件
rb 以读取模式打开二进制文件
wb 在写入模式下打开二进制文件
ab 以附加模式打开二进制文件
rb+ 以读写模式打开二进制文件
wb+ 以读写模式打开二进制文件
ab+ 以读写模式打开二进制文件

例如,下面代码表示以“只读”方式打开文本文件 f01.txt:

FILE *fp;   //定义文件指针
fp = fopen("f01.txt","r");   //打开文件

关闭文件

int fclose(FILE *fp);

如果成功关闭文件,fclose()函数返回零,如果关闭文件时发生错误,函数返回EOF。这个函数实际上,会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。EOF是一个定义在头文件stdio.h中的常量。

写入文件

int fputc(int c, FILE *fp);

函数fputc()把参数c的字符值写入到fp所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回EOF。您可以使用下面的函数来把一个以null结尾的字符串写入到流中:

int fputs(const char *s, FILE *fp);

函数fputs()把字符串s写入到fp所指向的输出流中。如果写入成功,它会返回一个非负值,如果发生错误,则会返回EOF。

fprintf()函数用于将一组字符写入文件。它将格式化的输出发送到流。

fprintf()函数的语法如下:

int fprintf(FILE *stream, const char *format [, argument, ...])

示例:

创建一个源文件:fprintf-write-file.c,其代码如下 -

#include <stdio.h>  
int main() {
    FILE *fp;
    fp = fopen("file.txt", "w");//opening file  
    fprintf(fp, "Hello file by fprintf...\n");//writing data into file  
    fclose(fp);//closing file  
    printf("Write to file : file.txt finished.");
    return 0;
}

执行上面示例代码,得到以下结果 -

Write to file : file.txt finished.

打开filehadling 目录下,应该会看到一个文件:file.txt 。

读取文件

下面是从文件读取单个字符的最简单的函数:

int fgetc(FILE *fp);

fgetc() 函数从fp所指向的输入文件中读取一个字符。返回值是读取的字符,如果发生错误则返回EOF。下面的函数允许您从流中读取一个字符串:

char *fgets(char *buf, int n, FILE *fp);

函数fgets()从fp所指向的输入流中读取n - 1个字符。它会把读取的字符串复制到缓冲区buf,并在最后追加一个null字符来终止字符串。

如果这个函数在读取最后一个字符之前就遇到一个换行符'\n'或文件的末尾EOF,则只会返回读取到的字符,包括换行符。您也可以使用int fscanf(FILE *fp, const char *format, ...) 函数来从文件中读取字符串,但是在遇到第一个空格字符时,它会停止读取。

fscanf()函数用于从文件中读取一组字符。它从文件读取一个单词,并在文件结尾返回EOF。

fscanf()函数的语法如下:

int fscanf(FILE *stream, const char *format [, argument, ...])

示例:

创建一个源文件:fscanf-read-file.c,其代码如下 -

#include <stdio.h>  
main(){  
   FILE *fp;  
   char buff[255];//creating char array to store data of file  
   fp = fopen("file.txt", "r");  
   while(fscanf(fp, "%s", buff)!=EOF){  
   printf("%s ", buff );  
   }  
   fclose(fp);  
}

执行上面示例代码,得到以下结果 -

Hello file by fprintf...

文件的当前读写位置指针

文件打开后会有一个指针表示当前的读写位置。用 fgetc( ) 读取一个字符后,文件的读写位置指针会自动移动到下一个字符的位置;用 fscanf( ) 读取格式数据后,文件的读写位置指针则会自动移动到下一个格式数据的位置。

此外,C语言还提供了一个标准函数 rewind( ),它可以将文件的当前读写位置指针重新定位到文件的开头。

rewind(文件指针);    //将文件的当前读写位置指针重新定位在文件的开头

文件结束标识

无论操作系统实际使用何种方法检测文件结尾,在C语言中,用getchar()读取文件检测到文件结尾时将返回一个特殊的值,即EOF(end of file的缩写)。scanf()函数检测到文件结尾时也返回EOF。通常,EOF定义在stdio.h文件中:

#define EOF (-1)

为什么是-1?因为getchar()函数的返回值通常都介于0 ~ 127,这些值对应标准字符集。但是,如果系统能识别扩展字符集,该函数的返回值可能在0 ~ 255。无论哪种情况,-1都不对应任何字符,所以,该值可用于标识文件结尾。

#include <stdio.h>
int main(void) {
    int ch;
    while ((ch = getchar()) != EOF) {
        putchar(ch);
    }
    return 0;
}

C语言中,由文件结尾标识符“EOF”标识文件的结尾,在文件读写操作中用它来表示文件的结束。此外,C语言还提供了一个标准函数 feof( ),它可以判断文件当前读写位置指针是否到达文件末尾,如果在文件末尾,则返回 1;否则返回 0。

feof(文件指针);     //判断文件读写指针是否到达文件末尾,是,则返回 1

例如:

rewind(fp);          //将文件的当前读写位置指针重新定位到文件开头
printf(feof(fp));    //输出函数 feof(fp) 的值

输出值为 0,因为函数 rewind(fp) 将 fp 所指向的文件当前读写位置指针设置到了文件开头,它并不在文件结尾,因而函数 feof(fp) 的值为 0。

  • 表达式!feof(fp)为真表示尚未到达文件结尾;
  • 表达式(ch = fgetc(fp)) != EOF为真也表示尚未到达文件结尾。

错误处理

C语言不提供对错误处理的直接支持,但是作为一种系统编程语言,它以返回值的形式允许您访问底层数据。
在发生错误时,大多数的C或UNIX函数调用返回1或NULL,同时会设置一个错误代码errno,该错误代码是全局变量,表示在函数调用期间发生了错误。您可以在errno.h 头文件中找到各种各样的错误代码。

所以,C程序员可以通过检查返回值,然后根据返回值决定采取哪种适当的动作。开发人员应该在程序初始化时,把errno设置为0,这是一种良好的编程习惯。0值表示程序中没有错误。

errno、perror()和strerror()

C语言提供了perror()和strerror()函数来显示与errno相关的文本消息。

  • perror()函数显示您传给它的字符串,后跟一个冒号、一个空格和当前errno值的文本表示形式。
  • strerror()函数,返回一个指针,指针指向当前errno值的文本表示形式。
#include <stdio.h>
#include <errno.h>
#include <string.h>

extern int errno;

int main () {
    FILE *pf;
    int errnum;
    pf = fopen("unexist.txt", "rb");
    if (pf == NULL) {
        errnum = errno;
        fprintf(stderr, "错误号: %d\n", errno);
        perror("通过 perror 输出错误");
        fprintf(stderr, "打开文件错误: %s\n", strerror(errnum));
    } else {
        fclose (pf);
    }
    return 0;
}

执行结果:

错误号: 2
通过 perror 输出错误: No such file or directory
打开文件错误: No such file or directory

被零除的错误

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

int main() {
   int dividend = 20;
   int divisor = 0;
   int quotient;

   if(divisor == 0){
      fprintf(stderr, "除数为 0 退出运行...\n");
      exit(EXIT_FAILURE);
   }
   quotient = dividend / divisor;
   fprintf(stderr, "quotient 变量的值为 : %d\n", quotient);
   exit(EXIT_SUCCESS);
   return 0;
}

  • 邮箱 :charon.chui@gmail.com
  • Good Luck!
本页由 Markdown 自动渲染 · 共 628 篇笔记