来源:我的博客站 OceanicKang |《C语言之文件操作》
###一、打开文件
####1、函数
- fopen(path, type)
####2、参数介绍
| 参数 | 类型 | 说明 | 备注 |
| :------------ | :------------ | :------------ |
| path | 字符串 | 文件路径 | 如"./hello.txt" |
| type | 字符串 | 读写类型 | 见下方【读写类型说明】 |
| return | 指针或EOF | 返回值 | 指针为文件指针,EOF即为文件打开失败 |
【读写类型说明】
- “r”
- 从头只读
- 文件必须存在
- “w”
- 从头写入,不读取
- 文件不存在则创建
- 文件存在则用空文本覆盖
- “a”
- 从尾写入,不读取
- 文件不存在则创建
- 文件存在则从文本尾部追加文本
- “r+”
- 从头读写
- 文件必须存在
- 写入时,从头开始覆盖相应字节大小的文本,之后的文本内容保留
- “w+”
- 从头读写
- 文件不存在则创建
- 文件存在则优先读取,写入之前进行空文本覆盖
- “a+”
- 从头读取,从尾写入
- 文件不存在则创建
- “b”
- 与上面六种结合,如"wb"、“w+b”、“ab”、“a+b”…
- 操作对象为二进制文件
###二、读取文本(单字符)
####1、函数
- fgetc(FILE *stream) — 函数
- getc(FILE *stream) — 宏定义
####2、参数介绍
| 参数 | 类型 | 说明 | 备注 |
| :------------ | :------------ | :------------ |
| stream | 指针 | 文件指针 | 需要读取的文件的指针,即fopen返回的文件指针 |
| return | 整形 | 返回值 | 文本对应的整形数 |
【注】每一次执行函数,文件指针都会下移一位
###二、读取文本(字符串)
####1、函数
- fgets(char *s, int size, FILE *stream) — 函数
####2、参数介绍
| 参数 | 类型 | 说明 | 备注 |
| :------------ | :------------ | :------------ |
| s | 指针 | 字符型指针 | 用于存放读取字符串的地址 |
| size | 整形 | 字符长度 | 指定读取的字符长度,如要读取10个字符,则size设置为11,因为最后还有个’\0’ |
| stream | 指针 | 文件指针 | 需要读取的文件的指针,即fopen返回的文件指针 |
| return | 指针或EOF或NULL | 返回值 | 见【注】 |
【注】
- 读取到换行符’\n’或者文件结束符EOF时结束
- 如果函数调用成功,返回s所指向的地址
- 如果读取过程中遇到EOF,则返回EOF,s的内容发生改变
- 如果没有读取任何字符就遇到EOF,则s所指向的内容保持不变,函数返回NULL
- 如果读取过程中发生错误,则函数返回NULL,s所指向的内容可能发生改变
###三、写入文本(单字符)
####1、函数
- fputc(int c, FILE *stream) — 函数
- putc(int c, FILE *stream) — 宏定义
####2、参数介绍
| 参数 | 类型 | 说明 | 备注 |
| :------------ | :------------ | :------------ |
| c | 整形 | 字符 | 字符的ASCII码 |
| stream | 指针 | 文件指针 | 需要被写入的文件的指针 |
| return | 整形 | 返回值 | 写入字符的ASCII码 |
###三、写入文本(字符串)
####1、函数
- fputs(const char *s, FILE *stream) — 函数
####2、参数介绍
| 参数 | 类型 | 说明 | 备注 |
| :------------ | :------------ | :------------ |
| s | 指针 | 字符型指针 | 用于存放待写入字符串的地址 |
| stream | 指针 | 文件指针 | 需要被写入的文件的指针 |
| return | 整形或EOF | 返回值 | 见【注】 |
【注】
- 如果函数调用成功,返回一个非0值
- 如果函数调用失败,返回EOF
###四、补充
- feof(FILE *stream)
- 遇到文件结束符EOF返回非0值
- 没有遇到文件结束符EOF返回0
- 概括:文件结束即为真,文件未结束即为假
###五、例子
####1、fgetc()和fputc()
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp1;
FILE *fp2;
int ch;
// 打开./hello.txt文件
// 因为我不需要对这个文件做写入操作,所以选择 "r"只读模式
if ((fp1 = fopen("./hello.txt", "r")) == NULL) {
perror("打开文件失败!");
exit(EXIT_FAILURE);
}
// 打开./oceanickang.txt文件
// 由于当前目录下没有该文件
// 我需要创建、写入并且打印内容查看效果(即读取),可以选择 "w+"或者"a+"
// 我选择了"w+",因为覆盖空文本可以方便后续测试。"a+"在写入操作时是直接追加文本,不方便测试
if ((fp2 = fopen("./oceanickang.txt", "w+")) == NULL) {
perror("打开文件失败!");
exit(EXIT_FAILURE);
}
// 循环获取fp1的文本内容,并写入fp2
while((ch = fgetc(fp1)) != EOF) {
fputc(ch, fp2);
}
rewind(fp2); // 初始化fp2的指针指向
// 循环获取fp2的文本内容,并打印
while((ch = fgetc(fp2)) != EOF) {
putchar(ch);
}
// 千万不要忘了关闭文件!!!
fclose(fp1);
fclose(fp2);
return 0;
}
####2、fgets()和fputs()
#include <stdio.h>
#include <stdlib.h>
#define MAX 1024
int main(void)
{
FILE *fp;
// 写入字符串 ************************************/
if ((fp = fopen("./string.txt", "w")) == NULL) {
perror("打开文件失败");
exit(EXIT_FAILURE);
}
// 三种字符串存储格式
fputs("string 1: Hello!\n", fp); // 直接赋值字符串
char *p = "string 2: World!\n";
fputs(p, fp); // 指针存放字符串
char buffer[MAX] = "string 3: OceanicKang!\n";
fputs(buffer, fp); // 数组存放字符串
fclose(fp);
// 读取字符串 ************************************/
char string[MAX];
if ((fp = fopen("./string.txt", "r")) == NULL) {
perror("打开文件失败!");
exit(EXIT_FAILURE);
}
// fgets()遇到'\n'就结束本次读取
// 根据上面的三个字符串可以知道,总共有三个'\n'
// 因此,前三次读取均到'\n'结束,第四次读取才会遇到文件结束符EOF
// 故这个循环总共执行四次
// string 3 被打印了两次
while(!feof(fp)) {
fgets(string, MAX, fp);
printf("%s", string);
}
fclose(fp);
return 0;
}