有关C语言编程处理标准输入和输出设备将在最后一章解释。在本章我们将看到C程序员如何创建其数据存储:打开,关闭文本文件或二进制文件。
文件代表了一个字节序列,如果它是一个文本文件或二进制文件也不要紧。 C语言编程语言提供了高层次的功能接入以及低级别(OS级别)调用来处理存储设备和文件。本章将引导完成对文件管理的重要调用。
打开文件
可以使用 fopen()函数来创建一个新的文件或打开现有的文件,这个调用将初始化文件类型的对象,其中包含必要的控制流的所有信息。下面是这个函数调用的原型:
FILE *fopen( const char * filename, const char * mode );
在这里,文件名(filename)是字符串文字,用它来命名文件,访问模式可以是以下值之一:
模式 | 描述 |
---|---|
r | 打开读取目的,现有的文本文件 |
w | 打开用于写入的文本文件,如果它不存在,则创建一个新文件。在这里程序将开始从文件的开头写入内容 |
a | 打开用于写入附加模式中,如果它不存在,则创建一个新文件的文本文件。在这里,程序将内容追加到文件现有内容 |
r+ | 打开用于读取和写入两种的文本文件 |
w+ | 打开用于读取和写入两种的文本文件。它首先截断文件为零长度,如果它存在,否则创建该文件,如果它不存在 |
a+ | 打开用于读取和写入两种的文本文件。它,如果它不存在,创建该文件。读数将从头开始,但写只能追加 |
如果要处理二进制文件,那么可使用以下提到的接入方式,而不是上面提到的,具体如下:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
关闭一个文件
关闭文件,使用fclose()函数。这个函数的原型是:
int fclose( FILE *fp );
fclose()函数成功则返回零,或EOF - 如果在关闭文件中的错误。此函数其实刷新任何数据仍待在缓冲区里的文件,关闭文件,并释放用于文件的内存。EOF是在头文件stdio.h中定义的常数。
由C标准库提供用来读取和字符,在一个固定长度串形式写入文件的字符的各种功能。让我们看看一小部分在下一个章节。
写入文件
以下是写入单个字符到一个流的最简单的函数:
int fputc( int c, FILE *fp );
fputc()函数将参数的字符值c写入由fp引用的输出流。它返回书面字符如果写入成功,否则返回EOF-如果有错误。可以使用下面的函数写一个空值终止字符串流:
int fputs( const char *s, FILE *fp );
函数fputs()写入字符串s到由fp引用的输出流。它在成功时返回一个非负值,否则返回EOF表示错误。可以使用fprintf(FILE *fp,const char *format, ...) 函数以及写一个字符串到一个文件中。试试下面的例子:
请确保有/tmp目录可用,如果没有则继续之前,必须机器上创建这个目录。
#include <stdio.h> main() { FILE *fp; fp = fopen("/tmp/test.txt", "w+"); fprintf(fp, "This is testing for fprintf... "); fputs("This is testing for fputs... ", fp); fclose(fp); }
当上面的代码被编译和执行,它会在/tmp目录中的新文件test.txt并写入使用两个不同的函数。让我们在阅读下一节此文件。
读取文件
下面是最简单的函数来从文件中读取一个字符:
int fgetc( FILE * fp );
fgetc() 函数读取由fp引用的输入文件的字符。返回值是读取的字符,或在任何错误则返回EOF。下列功能允许读取流字符串:
char *fgets( char *buf, int n, FILE *fp );
函数fgets()从fp引用的输入流读取多达 n - 1个字符。它会将读串入缓冲区buf,追加空(null)字符终止字符串。
如果该函数遇到换行符' '或文件EOF在结束之前,已经读读的最大字符数,则仅返回字符读取到这一点,包括新行字符。也可以使用 int fscanf(FILE *fp, const char *format, ...) 函数从文件中读取的字符串,但它读取遇到第一个空格字符后停止。
#include <stdio.h> main() { FILE *fp; char buff[255]; fp = fopen("/tmp/test.txt", "r"); fscanf(fp, "%s", buff); printf("1 : %s ", buff ); fgets(buff, 255, (FILE*)fp); printf("2: %s ", buff ); fgets(buff, 255, (FILE*)fp); printf("3: %s ", buff ); fclose(fp); }
当上述代码被编译和执行时,它读取在前面的部分中创建的文件,并且产生以下结果:
1 : This 2: is testing for fprintf... 3: This is testing for fputs...
让我们来看看更多的细节,看看这里发生什么。首先fscanf()方法读取只是因为这之后它遇到了一个空格,第二次调用fgets()读取剩余行,直到它遇到行尾。最后调用fgets()读完第二行。
二进制I/O函数
有以下两个函数可以用于二进制输入和输出:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file); size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
这两个函数用来读或写存储器块 - 通常是数组或结构。