一、文件操作基础
在C语言中,文件操作主要通过文件描述符(file descriptor)来进行。文件描述符是一个整数,用于标识一个打开的文件。通常,文件描述符与标准输入输出设备相关联,例如标准输入的文件描述符是0,标准输出的文件描述符是1。
文件操作的基本步骤包括:打开文件、读写文件、关闭文件。
二、文件打开与关闭
1. 文件打开
在C语言中,使用fopen
函数打开文件。该函数的原型为:
FILE *fopen(const char *path, const char *mode);
其中,path
参数是文件的路径,mode
参数是文件打开模式。常用的打开模式有:
"r"
:以只读方式打开文件;"w"
:以写入方式打开文件,如果文件不存在,则创建文件;"a"
:以追加方式打开文件,如果文件不存在,则创建文件;"rb"
: 为了输入数据打开一个二进制文件;"wb"
: 为了输出数据打开一个二进制文件,如果文件不存在,则创建文件;"ab"
: 以追加方式打开二进制文件,如果文件不存在,则创建文件;"r+"
:以读写方式打开文件;"w+"
:以读写方式打开文件,如果文件不存在,则创建文件;"a+"
:以读写方式打开文件,如果文件不存在,则创建文件;"rb+"
: 为了读写打开一个二进制文件;"wb+"
: 为了读写数据打开一个二进制文件,如果文件不存在,则创建文件;"ab+"
: 为了读写以追加方式打开二进制文件,如果文件不存在,则创建文件;
示例:
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("打开文件失败");
return -1;
}
// 写文件操作
fclose(fp);
return 0;
}
2. 文件关闭
在C语言中,使用fclose
函数关闭文件。该函数的原型为:
int fclose(FILE *stream);
示例:
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("打开文件失败");
return -1;
}
// 读写文件操作
fclose(fp);
return 0;
}
三、文件读写
1. 文件读取
在C语言中,使用fread
函数读取文件。该函数的原型为:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
其中,ptr
参数是输出缓冲区,size
参数是每个数据项的大小,nmemb
参数是要读取的数据项数量,stream
参数是文件描述符。
示例:
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("打开文件失败");
return -1;
}
char buffer[1024];
size_t bytesRead = fread(buffer, 1, sizeof(buffer), fp);
if (bytesRead == 0) {
perror("读取文件失败");
fclose(fp);
return -1;
}
printf("读取到的内容:%s\n", buffer);
fclose(fp);
return 0;
}
2. 文件写入
在C语言中,使用fwrite
函数写入文件。该函数的原型为:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
其中,ptr
参数是输入缓冲区,size
参数是每个数据项的大小,nmemb
参数是要写入的数据项数量,stream
参数是文件
示例:
#include <stdio.h>
int main() {
FILE *fp;
int data[] = {1, 2, 3, 4, 5};
int size = sizeof(data) / sizeof(data[0]);
fp = fopen("output.txt", "wb"); // 打开文件以写入二进制数据
if (fp == NULL) {
printf("无法打开文件\n");
return 1;
}
fwrite(data, sizeof(int), size, fp); // 将数据写入文件
fclose(fp); // 关闭文件
printf("数据已成功写入文件\n");
return 0;
}
以下是一些常用的顺序读写函数
1. fgetc函数
fgetc
函数用于从文件流中读取一个字符。其原型如下:
int fgetc(FILE *stream);
该函数读取stream
指定的文件流中的下一个字符,并将其返回为整数(其值通常是该字符的ASCII码)。如果到达文件末尾,则返回EOF
。
示例:
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("打开文件失败");
return -1;
}
int ch;
while ((ch = fgetc(fp)) != EOF) {
putchar(ch); // 将读取的字符打印到标准输出
}
fclose(fp);
return 0;
}
2. fputc函数
fputc
函数用于将一个字符写入文件流。其原型如下:
int fputc(int ch, FILE *stream);
该函数将字符ch
写入到stream
指定的文件流中,并返回ch
。如果写入失败,返回EOF
。
示例:
#include <io.h>
int main() {
FILE *fp = fopen("example.txt", "w");
if (fp == NULL) {
perror("打开文件失败");
return -1;
}
char ch = 'A';
while (ch <= 'Z') {
fputc(ch, fp); // 将字符写入文件
ch++;
}
fclose(fp);
return 0;
}
3. fgets函数
fgets
函数用于从文件流中读取一行文本。其原型如下:
char *fgets(char *str, int n, FILE *stream);
该函数从stream
指定的文件流中读取最多n-1
个字符,并将其存储在字符串str
中。如果读取成功,返回str
;如果到达文件末尾,返回NULL
。
示例:
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("打开文件失败");
return -1;
}
char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer); // 打印读取的文本行
}
fclose(fp);
return 0;
}
4. fputs函数
fputs
函数用于将一个字符串写入文件流。其原型如下:
int fputs(const char *str, FILE *stream);
该函数将字符串str
写入到stream
指定的文件流中,直到遇到字符串结束符'\0'
。如果写入成功,返回0
;如果写入失败,返回EOF
。
示例:
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "w");
if (fp == NULL) {
perror("打开文件失败");
return -1;
}
const char *str = "Hello, World!\n";
fputs(str, fp); // 将字符串写入文件
fclose(fp);
return 0;
}
当然可以!fprintf
和fscanf
是C语言中常用的两个函数,用于向文件写入格式化的输出和从文件读取格式化的输入。
5. fprintf函数
fprintf
函数用于将格式化的输出写入文件。其原型如下:
int fprintf(FILE *stream, const char *format, ...);
其中,stream
是指向要写入的文件的指针,format
是一个格式化字符串,后面的参数按照格式化字符串中的格式进行输出。
示例用法:
FILE *fp = fopen("example.txt", "w");
if (fp != NULL) {
fprintf(fp, "姓名:%s,年龄:%d\n", "张三", 25);
fclose(fp);
}
上述代码将字符串"姓名:张三,年龄:25"写入到名为"example.txt"的文件中。
6. fscanf函数
fscanf
函数用于从文件中读取格式化的输入。其原型如下:
int fscanf(FILE *stream, const char *format, ...);
其中,stream
是指向要读取的文件的指针,format
是一个格式化字符串,后面的参数按照格式化字符串中的格式进行解析并读取文件中的数据。
示例用法:
FILE *fp = fopen("example.txt", "r");
if (fp != NULL) {
char name[50];
int age;
fscanf(fp, "姓名:%s,年龄:%d\n", name, &age);
printf("姓名:%s,年龄:%d\n", name, age);
fclose(fp);
}
上述代码从名为"example.txt"的文件中读取字符串"姓名:张三,年龄:25",并将其存储在变量name
和age
中,并打印出来。
四、文件的随机读取
文件随机读写是通过fseek
、ftell
和rewind
三个函数来实现的。
1. fseek函数
fseek
函数用于改变文件指针的位置,使其指向文件的特定位置。其原型如下:
int fseek(FILE *stream, long int offset, int origin);
stream
:指向FILE对象的指针。offset
:从origin
指定的位置开始的偏移量。origin
:可以取以下值之一:SEEK_SET
:表示从文件的开头开始计算偏移量(0)。SEEK_CUR
:表示从当前文件指针的位置开始计算偏移量。SEEK_END
:表示从文件的末尾开始计算偏移量(文件大小)。
示例:
#include <stdio.h>
int main() {
FILE *fp;
int data[] = {1, 2, 3, 4, 5};
int size = sizeof(data) / sizeof(data[0]);
fp = fopen("example.txt", "w+"); // 以读写模式打开文件
if (fp == NULL) {
perror("打开文件失败");
return 1;
}
fwrite(data, sizeof(int), size, fp); // 写入数据
fseek(fp, 2, SEEK_SET); // 设置文件指针到文件开头的第3个字节
printf("当前偏移量:%ld\n", ftell(fp)); // 打印当前偏移量
fwrite(data, sizeof(int), 1, fp); // 从当前位置写入1个字节
fclose(fp);
return 0;
}
在这个例子中,我们首先以读写模式打开一个文件,然后写入一些数据。接着,我们使用fseek
函数将文件指针移动到文件开头的第3个字节,并使用ftell
函数打印出当前的偏移量。最后,我们从当前位置写入1个字节,然后关闭文件。
2. ftell函数
ftell
函数用于获取当前文件指针的位置。其原型如下:
long int ftell(FILE *stream);
返回值:当前文件指针的位置(相对于文件开始的位置)。
示例:
#include <stdio.h>
int main() {
FILE *fp;
int data[] = {1, 2, 3, 4, 5};
int size = sizeof(data) / sizeof(data[0]);
fp = fopen("example.txt", "w+"); // 以读写模式打开文件
if (fp == NULL) {
perror("打开文件失败");
return 1;
}
fwrite(data, sizeof(int), size, fp); // 写入数据
fseek(fp, 2, SEEK_SET); // 设置文件指针到文件开头的第3个字节
printf("当前偏移量:%ld\n", ftell(fp)); // 打印当前偏移量
fclose();
return 0;
}
3. rewind函数
rewind
函数用于将文件指针返回到文件的开头。其原型如下:
void rewind(FILE *stream);
示例:
#include <stdio.h>
int main() {
FILE *fp;
int data[] = {1, 2, 3, 4, 5};
int size = sizeof(data) / sizeof(data[0]);
fp = fopen("example.txt", "w+"); // 以读写模式打开文件
if (fp == NULL) {
perror("打开文件失败");
return 1;
}
fwrite(data, sizeof(int), size, fp); // 写入数据
fseek(fp, 2, SEEK_SET); // 设置文件指针到文件开头的第3个字节
rewind(fp); // 将文件指针返回到文件开头
printf("当前偏移量:%ld\n", ftell(fp)); // 打印当前偏移量
fclose(fp);
return 0;
}
在这个例子中,我们首先以读写模式打开一个文件,然后写入一些数据。接着,我们使用fseek
函数将文件指针移动到文件开头的第3个字节,并使用rewind
函数将文件指针返回到文件的开头。然后,我们使用ftell
函数打印出当前的偏移量,最后关闭文件。
五、文件读取结束的判定
1被错误使用的 feof
牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。
feof
的作用是:当文件读取结束的时候,判断是读取结束的原因是否是:遇到文件尾结束。
- 文本文件读取是否结束,判断返回值是否为
EOF
( fgetc ),或者NULL
( fgets )
例如:
• fgetc 判断是否为 EOF 。
• fgets 判断返回值是否为 NULL 。 - 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数
例如:
• fread判断返回值是否小于实际要读的个数。