C语言提供了一组文件操作函数,用于对文件进行读取、写入、打开、关闭等操作。下面将介绍常用的文件操作函数。
本文包含了文件操作的大部分知识内容,如果只是应付考试,请点击这里查看考试范围内的内容
一、打开和关闭文件
文件操作的第一步是打开文件。C语言中使用 fopen() 函数打开文件,其原型如下:
FILE *fopen(const char *filename, const char *mode);
filename 参数是要打开的文件的文件名,mode 参数是文件打开模式,通常有以下几种模式:
- “r”:只读模式,打开一个已有的文本文件,文件指针在文件的开头。
- “w”:只写模式,打开一个文本文件,如果文件已存在则文件会被截断为空,文件指针在文件的开头。
- “a”:追加模式,打开一个文本文件,如果文件已存在则文件指针移到文件的末尾,否则创建一个新文件。
- “rb”、“wb”、“ab”:二进制模式,与上述模式类似,但是是针对二进制文件的。
如果文件打开成功,函数返回一个指向 FILE 结构体的指针,该结构体包含了与文件有关的信息,如文件指针、缓冲区等。如果文件打开失败,函数返回 NULL。
文件操作完成后需要关闭文件,C语言中使用 fclose() 函数关闭文件,其原型如下:
int fclose(FILE *stream);
该函数将 stream 所指向的文件关闭,并将该文件所占用的资源释放掉。如果函数执行成功,返回值为 0,否则返回 EOF。
二、读取和写入文件
打开文件之后,可以使用 fscanf()、fgets()、fread() 等函数读取文件,或使用 fprintf()、fputs()、fwrite() 等函数向文件中写入数据。
其中,fscanf() 函数用于从文件中读取格式化的数据,其原型如下:
int fscanf(FILE *stream, const char *format, ...);
stream 参数是指向要读取的文件的指针,format 参数是格式控制字符串,后面的参数根据格式控制字符串指定的格式来读取文件中的数据。
fgets() 函数用于从文件中读取一行字符串,其原型如下:
char *fgets(char *s, int size, FILE *stream);
fgets() 从 stream 指向的文件中读取一行,最多读取 size - 1 个字符,将它们存储到 s 指向的字符数组中,最后加上一个空字符 ‘\0’。如果读取到文件末尾或出现错误,返回 NULL。
fread() 函数用于从文件中读取二进制数据,其原型如下:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr参数是要读取数据的缓冲区指针,size 参数是要读取的每个数据项的字节数,nmemb 参数是要读取的数据项的数量,stream 参数是指向要读取的文件的指针。fread() 函数返回成功读取的数据项数目。
fprintf() 函数用于向文件中写入格式化的数据,其原型如下:
int fprintf(FILE *stream, const char *format, ...);
stream 参数是指向要写入的文件的指针,format 参数是格式控制字符串,后面的参数根据格式控制字符串指定的格式来写入数据。
fputs() 函数用于向文件中写入字符串,其原型如下:
int fputs(const char *s, FILE *stream);
fputs() 将字符串 s 写入到 stream 指向的文件中,如果成功,返回一个非负整数,否则返回 EOF。
fwrite() 函数用于向文件中写入二进制数据,其原型如下:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr 参数是要写入的数据的缓冲区指针,size 参数是要写入的每个数据项的字节数,nmemb 参数是要写入的数据项的数量,stream 参数是指向要写入的文件的指针。fwrite() 函数返回成功写入的数据项数目。
三、示例
下面是一个示例程序,演示了如何使用文件操作函数读取和写入文件:
#include <stdio.h>
int main()
{
FILE *in_file, *out_file;
char in_filename[] = "input.txt";
char out_filename[] = "output.txt";
char buffer[256];
in_file = fopen(in_filename, "r");
if (in_file == NULL) {
printf("Failed to open input file!\n");
return 1;
}
out_file = fopen(out_filename, "w");
if (out_file == NULL) {
printf("Failed to open output file!\n");
return 1;
}
while (fgets(buffer, sizeof(buffer), in_file)) {
fprintf(out_file, "%s", buffer);
}
fclose(in_file);
fclose(out_file);
return 0;
}
该程序将打开一个名为 “input.txt” 的文件,逐行读取文件中的数据,然后将数据写入一个名为 “output.txt” 的文件中。如果文件打开失败,程序将输出错误消息,并返回一个非零值。否则,程序将返回零。
1. 文件定位
文件操作中常用的一个概念是文件定位。文件定位指的是在文件中的某个位置读取或写入数据。
在 C 语言中,使用 fseek() 函数进行文件定位。其原型如下:
int fseek(FILE *stream, long offset, int whence);
stream 参数是要定位的文件指针,offset 参数是定位的偏移量,whence 参数是定位的起始位置。
whence 参数可以取以下值:
SEEK_SET:从文件开头计算偏移量。SEEK_CUR:从当前位置计算偏移量。SEEK_END:从文件结尾计算偏移量。
例如,要将文件指针移动到文件开头,可以使用如下代码:
fseek(fp, 0, SEEK_SET);
2. 文件截取
有时候,需要截取文件的一部分,或者将文件扩展到一个更大的尺寸。在 C 语言中,可以使用 ftruncate() 函数截取文件。其原型如下:
int ftruncate(int fd, off_t length);
fd 参数是文件描述符,length 参数是截取后文件的大小。如果截取成功,ftruncate() 函数将返回零,否则返回 -1。
3. 错误处理
在文件操作中,如果出现错误,需要进行错误处理。C 语言提供了 perror() 和 ferror() 函数来处理文件操作的错误。
perror() 函数可以打印出一个错误消息,并输出一个与当前错误号对应的错误消息。其原型如下:
void perror(const char *s);
s 参数是一个字符串,用于描述发生错误的上下文信息。例如,下面的代码可以输出 “Failed to open file: input.txt”:
FILE *fp = fopen("input.txt", "r");
if (fp == NULL) {
perror("Failed to open file");
}
ferror() 函数可以检查文件操作是否出现了错误。其原型如下:
int ferror(FILE *stream);
stream 参数是要检查的文件指针。如果文件操作出现了错误,ferror() 函数将返回一个非零值,否则返回零。
4. 文件操作示例
下面是一个使用文件操作的示例程序。该程序从一个文本文件中读取数据,将其转换为大写形式,并输出到另一个文件中。
#include <stdio.h>
#include <ctype.h>
int main() {
FILE *fp_in = fopen("input.txt", "r");
if (fp_in == NULL) {
perror("Failed to open input file");
return 1;
}
FILE *fp_out = fopen("output.txt", "w");
if (fp_out == NULL) {
perror("Failed to open output file");
return 1;
}
int c;
while ((c = fgetc(fp_in)) != EOF) {
fputc(toupper(c), fp_out);
}
if (ferror(fp_in)) {
perror("Error reading input file");
return 1;
}
if (ferror(fp_out)) {
perror("Error writing output file");
return 1;
}
fclose(fp_in);
fclose(fp_out);
return 0;
}
该程序首先使用 fopen() 函数打开输入文件和输出文件,如果文件打开失败,就输出一个错误消息并退出。
接下来,程序使用 fgetc() 函数从输入文件中读取一个字符,并使用 toupper() 函数将其转换为大写形式。然后,程序使用 fputc() 函数将字符写入输出文件中。
程序通过检查 ferror() 函数来检查文件操作是否出现错误。如果出现错误,就输出一个错误消息并退出。
最后,程序使用 fclose() 函数关闭输入文件和输出文件。
四、大一基础综合案例
大一C语言基础部分需要掌握的文件操作部分包括:
- 文件打开和关闭:使用
fopen()函数打开文件,并使用fclose()函数关闭文件。 - 文件读取和写入:使用
fread()和fwrite()函数进行二进制数据的读写;使用fscanf()和fprintf()函数进行文本数据的读写。 - 文件定位:使用
fseek()函数进行文件定位,可以在文件中的任何位置读取或写入数据。 - 文件错误处理:使用
ferror()和perror()函数处理文件操作中的错误。
注意:
文件定位与错误处理不是重点掌握内容,考生仅需掌握文件的打开,读写,关闭这三部曲。
下面是一个综合性的文件操作示例,该程序从输入文件中读取整数,计算它们的平均值,并将结果写入输出文件中。
#include <stdio.h>
int main() {
FILE *fp_in = fopen("input.txt", "r");
if (fp_in == NULL) {
perror("Failed to open input file");
return 1;
}
FILE *fp_out = fopen("output.txt", "w");
if (fp_out == NULL) {
perror("Failed to open output file");
return 1;
}
int n = 0;
int sum = 0;
int x;
while (fscanf(fp_in, "%d", &x) == 1) {
sum += x;
n++;
}
if (ferror(fp_in)) {
perror("Error reading input file");
return 1;
}
if (n > 0) {
double avg = (double) sum / n;
fprintf(fp_out, "Average: %.2f", avg);
} else {
fprintf(fp_out, "No data");
}
if (ferror(fp_out)) {
perror("Error writing output file");
return 1;
}
fclose(fp_in);
fclose(fp_out);
return 0;
}
该程序首先使用 fopen() 函数打开输入文件和输出文件,如果文件打开失败,就输出一个错误消息并退出。
接下来,程序使用 fscanf() 函数从输入文件中读取整数,并计算它们的平均值。如果输入文件中没有数据,程序将在输出文件中输出 “No data”。
程序通过检查 ferror() 函数来检查文件操作是否出现错误。如果出现错误,就输出一个错误消息并退出。
最后,程序使用 fclose() 函数关闭输入文件和输出文件。