标准文件
概述
磁盘文件和设备文件
- 磁盘文件:存储在磁盘介质上的文件
- 设备文件:操作系统把链接主机的设备看成文件
磁盘文件分类
- 文本文件:以编码存储在磁盘中
- 二进制文件:以值存储在磁盘中
图片解析
文件打开和关闭
文件指针
在C语言中用一个指针变量指向一个文件,这个指针称为文件指针。
typedef struct
{
short level; //缓冲区"满"或者"空"的程度
unsigned flags; //文件状态标志
char fd; //文件描述符
unsigned char hold; //如无缓冲区不读取字符
short bsize; //缓冲区的大小
unsigned char *buffer;//数据缓冲区的位置
unsigned ar; //指针,当前的指向
unsigned istemp; //临时文件,指示器
short token; //用于有效性的检查
}FILE;
-
FILE是系统使用typedef定义出来的有关文件信息的一种结构体类型,结构中含有文件名、文件状态和文件当前位置等信息。
-
声明FILE结构体类型的信息包含在头文件“stdio.h”中,一般设置一个指向FILE类型变量的指针变量,然后通过它来引用这些FILE类型变量。通过文件指针就可对它所指的文件进行各种操作。
C语言中有三个特殊的文件指针由系统默认打开,用户无需定义即可直接使用: -
stdin: 标准输入,默认为当前终端(键盘),我们使用的scanf、getchar函数默认从此终端获得数据。
-
stdout:标准输出,默认为当前终端(屏幕),我们使用的printf、puts函数默认输出信息到此终端。
-
stderr:标准出错,默认为当前终端(屏幕),我们使用的perror函数默认输出信息到此终端。
-
FILE* p
-
当我们使用C库函数fopen打开一个文件,它会返回一个指向该文件所有信息的指针。我们对文件进行读写都需要依赖这个指针
文件的打开
fopen()
每个文件在使用之前必须打开
#include <stdio.h>
FILE * fopen(const char * filename, const char * mode);
- 功能:打开文件
- 参数:
- filename:需要打开的文件名,根据需要加上路径
- mode:打开文件的模式设置
- 返回值:
- 成功:文件指针
- 失败:NULL
- mode:文件打开的方式(r,w,a,rb,wb,ab,ab,r+,w+,a+)
示例:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int myFopen()
{
// 打开文件
FILE* fp = NULL;
// 打开当前目录下的test.txt
// 以只读的方式打开文件,文件不存在会报错
// fp = fopen("test.txt", "r");
// 以只写的方式打开文件,文件不存在会新建,文件存在会清空
fp = fopen("test.txt", "w");
if (fp == NULL)
{
perror("fopen"); // fopen: No such file or directory
return -1;
}
// 关闭文件
fclose(fp);
}
int main()
{
myFopen();
return 0;
}
文件的关闭
#include <stdio.h>
int fclose(FILE * stream);
- 功能:
- 关闭先前fopen()打开的文件。此动作让缓冲区的数据写入文件中,并释放系统所提供的文件资源。
- 参数:
- stream:文件指针
- 返回值:
- 成功:0
- 失败:-1
文件的顺序读写
按照字符读写文件fgetc和fputc
写文件
#include <stdio.h>
int fputc(int ch, FILE * stream);
- 功能:
- 将ch转换为unsigned char后写入stream指定的文件中
- 参数:
- ch:需要写入文件的字符
- stream:文件指针
- 返回值:
- 成功:成功写入文件的字符
- 失败:返回-1
示例代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int myFputc()
{
FILE* fp = NULL;
fp = fopen("test.txt", "w");
// 字符方式写文件
char buf[] = "hello directory";
int n = sizeof(buf) / sizeof(buf[0]);
int ch;
for (int i = 0;i < n;i++)
{
ch = fputc(buf[i], fp);
printf("%c", buf[i]);
}
fclose(fp);
}
int main()
{
// 按字节写入文件
myFputc();
return 0;
}
读文件
#include <stdio.h>
int fgetc(FILE * stream);
- 功能:
- 从stream指定的文件中读取一个字符
- 参数:
- stream:文件指针
- 返回值:
- 成功:返回读取到的字符
- 失败:-1
示例代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int myFgetc()
{
// 字符方式读文件
char ch;
FILE* fp = NULL;
fp = fopen("test.txt", "r");
while (1)
{
ch = fgetc(fp);
//if(ch==EOF) // 判断文本文件结束符号,对二进制文件不能这样判断
// 判断文件结束
if (feof(fp) != 0) // 可以判断文本文件和二进制文件的结束符号
{
break;
}
// 输出读到的字符
putchar(ch);
}
fclose(fp);
}
int main()
{
myFgetc();
return 0;
}
强化练习:实现vim、cat命令
myvim.c文件
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(int argc, char* argv[])
{
// 判断是否有两个参数传进来
if (argc != 2)
{
printf("用法:xxx.exe 文件名");
return -1;
}
// 打开那个文件
char* file_name = argv[1];
// 声明一个写入字符的变量
char ch;
// 打开文件
FILE* fp = NULL;
fp = fopen(file_name, "w");
// 判断是否打开文件成功
if (fp == NULL)
{
perror("fopen");
return -2;
}
// 将字符写入文件
while (1)
{
// 获取写入字符
ch = getchar();
if (ch == ':')
{
ch = getchar();
if (ch == 'w')
{
ch = getchar();
if (ch == 'q')
{
break;
}
}
}
// 以字符写入文件
fputc(ch, fp);
}
// 关闭文件
fclose(fp);
return 0;
}
mycat.c文件
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("用法:xxx.exe 文件名");
return -1;
}
char* file_name = argv[1];
char ch;
FILE* fp = NULL;
fp = fopen(file_name, "r");
if (fp == NULL)
{
perror("fopen");
return -2;
}
while (feof(fp) == 0)
{
ch = fgetc(fp);
putchar(ch);
}
fclose(fp);
return 0;
}
按照行读写文件fgets和fputs
写文件
#include <stdio.h>
int fputs(const char * str, FILE * stream);
- 功能:
- 将str所指定的字符串写入到stream指定的文件中,字符串结束符 ‘\0’ 不写入文件。
- 参数:
- str:字符串
- stream:文件指针
- 返回值:
- 成功:0
- 失败:-1
示例代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int myFputs()
{
char* buf[] = { "hello world\n","wang\n","lingling\n" };
int n = sizeof(buf) / sizeof(buf[0]);
// 打开文件
FILE* fp = NULL;
fp = fopen("test.txt", "w");
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 按行写入到文件中
for (int i = 0;i < n;i++)
{
fputs(buf[i], fp);
}
fclose(fp);
return 0;
}
int main()
{
myFputs();
return 0;
}
读文件
#include <stdio.h>
char * fgets(char * str, int size, FILE * stream);
- 功能:
- 从stream指定的文件内读入字符,保存到str所指定的内存空间,
- 直到出现换行字符、读到文件结尾或是已读了size - 1个字符为止,
- 最后会自动加上字符 ‘\0’ 作为字符串结束。
- 参数:
- str:字符串
- size:指定最大读取字符串的长度(size - 1)
- stream:文件指针
- 返回值:
- 成功:成功读取的字符串
- 读到文件尾或出错: NULL
示例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int myFgets()
{
// 按照行读取文件
char buf[100] = { 0 };
FILE* fp = NULL;
fp = fopen("test.txt", "r");
// 失败返回-1
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 成功,开始读取
while (feof(fp) == 0)
{
// 空间初始化为0
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), fp);
printf("buf=%s\n", buf);
}
fclose(fp);
return 0;
}
int main()
{
myFgets();
return 0;
}
强化练习: 文件版四则运算
有个文件大小不确定,每行内容都是一个四则运算表达式,还没有算出结果,写一个程序,自动算出其结果后修改文件。
1.生成目标文件代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int bulidObj()
{
// 1.目标生成a.txt文件,文件中每行都是 四则运算表达式,但是没有结果
FILE* fp = NULL;
fp = fopen("a.txt", "w");
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 生成四则运算表达式 10*10=\n这种形式的
// 产生一个随机数
srand(time(NULL));
// n行表达式
int n = rand() % 20;
char buf[100] = { 0 };
// 定义两个int变量用来存取操作数
int a, b;
// 定义char变量用来存运算符“+ - * /”
char ch;
char opt[4] = { '+','-','*','/' };
for (int i = 0;i < n;i++)
{
a = rand() % 100;
b = rand() % 100;
ch = opt[rand() % 4];
// 指定格式输出到数组中
sprintf(buf, "%d%c%d=\n", a, ch, b);
// 使用fputs写入文件
fputs(buf, fp);
}
fclose(fp);
return 0;
}
int main()
{
bulidObj();
return 0;
}
2.算出结果重新写入到文件代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int sumObj()
{
char buf[100] = { 0 };
// 1.逐行读取文件数据
FILE* fp = NULL;
fp = fopen("a.txt", "r");
if (fp == NULL)
{
perror("fopen");
return -1;
}
int a, b;
char ch;
int s=0;
int n = 0;
// 将读取完算出结果的数据存储到sbuf中
char sbuf[20][100] = {0};
while (feof(fp) == 0)
{
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), fp);
// 如果读取到最后一行,直接跳过
if (strlen(buf) == 0)
break;
//puts(buf);
// 获取四则运算符表达式,生成结果
// 指定格式提取数组数据
sscanf(buf, "%d%c%d=", &a, &ch, &b);
switch (ch)
{
case '+':
s = a + b;
break;
case '-':
s = a - b;
break;
case '*':
s = a * b;
break;
case '/':
s = a / b;
break;
}
sprintf(sbuf[n], "%d%c%d=%d\n", a, ch, b, s);
n++;
}
fclose(fp);
// 3.生成的四则运算表达式和结果写入文件
fp = fopen("a.txt", "w");
if (fp == NULL)
{
perror("fopen");
return -2;
}
for (int i = 0;i < n;i++)
{
fputs(sbuf[i], fp);
}
fclose(fp);
return 0;
}
int main()
{
//bulidObj();
sumObj();
return 0;
}
按照格式化文件fprintf、fscanf
写文件
#include <stdio.h>
int fprintf(FILE * stream, const char * format, ...);
- 功能:
- 根据参数format字符串来转换并格式化数据,然后将结果输出到stream指定的文件中,指定出现字符串结束符 ‘\0’ 为止。
- 参数:
- stream:已经打开的文件
- format:字符串格式,用法和printf()一样
- 返回值:
- 成功:实际写入文件的字符个数
- 失败:-1
示例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int myFprintf()
{
FILE* fp = NULL;
fp = fopen("a.txt", "w");
if (fp == NULL)
{
perror("fopen");
return -1;
}
int num = fprintf(fp, "%d %d %d", 10, 20, 30);
printf("%d\n", num);
fclose(fp);
return 0;
}
int main()
{
myFprintf();
return 0;
}
读文件
#include <stdio.h>
int fscanf(FILE * stream, const char * format, ...);
- 功能:
- 从stream指定的文件读取字符串,并根据参数format字符串来转换并格式化数据。
- 参数:
- stream:已经打开的文件
- format:字符串格式,用法和scanf()一样
- 返回值:
- 成功:参数数目,成功转换的值的个数
- 失败: - 1
示例:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int myFscanf()
{
FILE* fp = NULL;
fp = fopen("a.txt", "r");
if (fp == NULL)
{
perror("fopen");
return -1;
}
int a = 0, b = 0, c = 0;
int num = fscanf(fp, "%d %d %d", &a, &b, &c);
printf("%d\n", num);
printf("a=%d b=%d c=%d", a, b, c);
fclose(fp);
return 0;
}
int main()
{
//myFprintf();
myFscanf();
return 0;
}
文件版排序(示例)
1.生成一个随机数文本
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int fileSort()
{
FILE* fp = NULL;
fp = fopen("b.txt", "w");
if (fp == NULL)
{
perror("fopen");
return -1;
}
srand(time(NULL));
for (int i = 0;i < 10;i++)
{
int num = rand() % 200;
fprintf(fp, "%d\n", num);
}
fclose(fp);
return 0;
}
int main()
{
fileSort();
return 0;
}
2.对文件里随机生成的数字进行排序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 按照指定格式写入文件函数
int myWriteFile()
{
FILE* fp = NULL;
fp = fopen("b.txt", "w");
if (fp == NULL)
{
perror("fopen");
return -1;
}
int buf[10] = { 0 };
int n = sizeof(buf) / sizeof(buf[0]);
for (int i = 0;i < n;i++)
{
fprintf(fp, "%d\n", buf[i]);
}
fclose(fp);
}
int mySort()
{
// 1.先用只读的方式把文件内容获取到
FILE* fp = NULL;
fp = fopen("b.txt", "r");
if (fp == NULL)
{
perror("fopen");
return -1;
}
int num = 0;
//定义一个数组,用来存取读出来的数据
int buf[10] = { 0 };
int n = 0;
while (feof(fp) == 0)
{
fscanf(fp, "%d\n", &num);
//printf("%d\n", num);
buf[n] = num;
n++;
}
fclose(fp);
// 2.对数组进行排序
for (int i = 0;i < n-1;i++) //冒泡排序的个数
{
for (int j = 0;j < n - 1 - i;j++) // 冒一个泡要比较的次数
{
if (buf[j] > buf[j+1])
{
int tmp = buf[j];
buf[j] = buf[j+1];
buf[j+1] = tmp;
}
}
}
// 3.把排序后的数据写会文件中
myWriteFile();
return 0;
}
int main()
{
mySort();
return 0;
}
按照块读写文件fread和fwrite
写文件
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- 功能:
- 以数据块的方式给文件写入内容
- 参数:
- ptr:准备写入文件数据的地址
- size: size_t 为 unsigned int类型,此参数指定写入文件内容的块数据大小
- nmemb:写入文件的块数,写入文件数据总大小为:size * nmemb
- stream:已经打开的文件指针
- 返回值:
- 成功:实际成功写入文件数据的块数目,此值和 nmemb 相等
- 失败:0
示例
// 定义一个学生结构体
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct stu
{
char name[50];
int id;
}STU;
int blockFwrite()
{
STU s[3] = { 0 };
for (int i = 0;i < 3;i++)
{
sprintf(s[i].name, "stu100%d", i);
s[i].id = i + 1;
}
FILE* fp = NULL;
fp = fopen("c.txt", "wb");
if (fp == NULL)
{
printf("fopen");
return -1;
}
// 块操作写文件
int ret = 0;
ret = fwrite(s, sizeof(STU), 3, fp);
printf("%d\n", ret);
fclose(fp);
return 0;
}
int main()
{
blockFwrite();
return 0;
}
读文件
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- 功能:以数据块的方式从文件中读取内容
- 参数:
- ptr:存放读取出来数据的内存空间
- size: size_t 为 unsigned int类型,此参数指定读取文件内容的块数据大小
- nmemb:读取文件的块数,读取文件数据总大小为:size * nmemb
- stream:已经打开的文件指针
- 返回值:
- 成功:实际成功读取到内容的块数,如果此值比nmemb小,但大于0,说明读到文件的结尾。
- 失败:0
示例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct stu
{
char name[50];
int id;
}STU;
int blockFread()
{
FILE* fp = NULL;
fp = fopen("c.txt", "rb");
if (fp == NULL)
{
printf("fopen");
return -1;
}
STU s2[3] = {0};
fread(s2, sizeof(STU), 3, fp);
for (int i = 0;i < 3;i++)
{
printf("s2:%s,%d\n", s2[i].name, s2[i].id);
}
fclose(fp);
return 0;
}
int main()
{
blockFread();
return 0;
}
强化训练:大文件拷贝
前提:需要设置两个命令行参数,设置方法->点击项目右键属性->调试->命令行参数->编辑->设置为123.mp4(这个文件你的项目目录中必须要有) 321.mp4(这个文件可以没有,没有会自己新建一个.mp4的文件)
图片解析
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[])
{
if (argc != 3)
{
printf("用法错误:xxx.exe 源文件 目标文件\n");
}
// 命令行指定源文件命令行参数,我这里默认以123.mp4为例
char* src_file = argv[1];
// 命令行指定目标文件命令行参数,我这里默认以321.mp4为例
char* dest_file = argv[2];
// 定义两个文件指针
FILE* fpw = NULL, * fpr = NULL;
// 以二进制只读的方式打开源文件
fpr = fopen(src_file, "rb");
if (fpr == NULL)
{
perror("src_fopen");
return -1;
}
// 以二进制只读的方式打开目标文件
fpw = fopen(dest_file, "wb");
if (fpw == NULL)
{
perror("dest_fopen");
fclose(fpr);
return -1;
}
// 向堆区申请一块空间用来存放读取的数据,并将数据写入到目标文件,完成拷贝
char* str = (char*)malloc(1024 * 1024);
int ret = 0;
while (feof(fpr) == 0)
{
memset(str, 0, 1024 * 1024);
ret = fread(str, 1, 1024 * 1024, fpr);
fwrite(str, 1, ret, fpw);
}
free(str);
fclose(fpr);
fclose(fpw);
return 0;
}
文件的随机读写
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
- 功能:移动文件流(文件光标)的读写位置。
- 参数:
- stream:已经打开的文件指针
- offset:根据whence来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence往右移动,如果是负数,则相对于whence往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再次写入时将增大文件尺寸。
- whence:其取值如下:
- SEEK_SET:从文件开头移动offset个字节
- SEEK_CUR:从当前位置移动offset个字节
- SEEK_END:从文件末尾移动offset个字节
- 返回值:
- 成功:0
- 失败:-1
#include <stdio.h>
long ftell(FILE *stream);
- 功能:获取文件流(文件光标)的读写位置。
- 参数:
- stream:已经打开的文件指针
- 返回值:
- 成功:当前文件流(文件光标)的读写位置
- 失败:-1
#include <stdio.h>
void rewind(FILE *stream);
- 功能:把文件流(文件光标)的读写位置移动到文件开头。
- 参数:
- stream:已经打开的文件指针
- 返回值:
- 无返回值
示例代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct stu
{
char name[50];
int id;
}STU;
int main()
{
// 打开文件
FILE* fp = NULL;
fp = fopen("c.txt", "rb");
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 对文件进行一系列操作
// 1.ftell获取文件指针当前文件光标
int offset = ftell(fp);
printf("文件当前偏移量:%d\n", offset);
// 2.fseek移动文件光标,SEEK_SET从文件开头开始,移动2 * sizeof(STU)字节
STU s3 = { 0 }, s[3] = {0};
fseek(fp, 2 * sizeof(STU), SEEK_SET);
offset = ftell(fp);
printf("文件当前偏移量:%d\n", offset);
int ret = fread(&s3, sizeof(STU), 1, fp);
if (ret == 1)
{
printf("获取到的第三个结构体:name:%s,id:%d\n", s3.name, s3.id);
}
// 回到文件的开头
//fseek(fp, 0, SEEK_SET);
rewind(fp);
fread(s, sizeof(STU), 3, fp);
for (int i = 0;i < 3;i++)
{
printf("s[%d]:\nname:%s,id:%d\n", i, s[i].name, s[i].id);
}
// 关闭文件
fclose(fp);
return 0;
}
Windows和Linux文本文件区别
- Windows下文本文件,写入’\n’时,系统会自动转换成’\r\n’,读取’\r\n’时,系统自动转换成’\n’
- Linux下文本文件,写入什么,读取就是什么
- Windows下二进制打开文件,写入什么,读取就是什么
示例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("用法:xxx.exe 文件名");
return -1;
}
char* file_name = argv[1];
// 打开文件
FILE* fp = NULL;
fp = fopen(file_name, "rb");
if (fp == NULL)
{
perror("fopen");
return -2;
}
// 对文件进行一系列操作
char buf[1024] = { 0 };
fread(buf, 1, 1024, fp);
int len = 0;
while (buf[len])
{
if (buf[len] == '\n')
{
if (buf[len - 1] == '\r')
{
printf("Windows Flies\n");
break;
}
else
{
printf("Linux Flies\n");
break;
}
}
len++;
}
// 关闭文件
fclose(fp);
return 0;
}
获取文件状态
#include <sys/types.h>
#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
- 功能:获取文件状态信息
- 参数:
- path:文件名
- buf:保存文件信息的结构体
- 返回值:
- 成功:0
- 失败-1
系统提供的stat结构体
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
示例
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("用法:xxx.exe 文件名");
return -1;
}
char* file_name = argv[1];
struct stat s = { 0 };
// 查看文件状态
stat(file_name, &s);
printf("文件大小:%d\n", s.st_size);
return 0;
}
删除文件、重命名文件
#include <stdio.h>
int remove(const char *pathname);
- 功能:删除文件
- 参数:
- pathname:文件名
- 返回值:
- 成功:0
- 失败:-1
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
- 功能:把oldpath的文件名改为newpath
- 参数:
- oldpath:旧文件名
- newpath:新文件名
- 返回值:
- 成功:0
- 失败: - 1
示例代码
#include <stdio.h>
int main(int argc, char* argv[])
{
//if (argc != 2)
//{
// printf("用法:xxx.exe 文件名\n");
// return -1;
//}
// 删除文件
//remove(argv[1]);
// 重命命名文件
if (argc != 3)
{
printf("用法:xxx.exe 旧的文件名 新的文件名\n");
return -1;
}
rename(argv[1], argv[2]);
return 0;
}
文件的缓冲区
- 文件缓冲区:实际文本读写操作,都是基于缓冲区操作。只有关闭文件或者缓冲区满了或者程序结束,缓冲区数据才会写入到文件。
- 磁盘文件的存取:
- 更新缓冲区:
#include <stdio.h>
int fflush(FILE *stream);
功能:更新缓冲区,让缓冲区的数据立马写到文件中。
参数:
stream:文件指针
返回值:
成功:0
失败:-1
磁盘文件存取示意图
示例代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
// 打开文件
FILE* fp = NULL;
fp = fopen("demo.txt","w");
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 对文件进行操作
fputs("hello world", fp);
// 刷新缓冲区,写入文件
fflush(fp);
// 写一个死循环测试文件实际存到了缓冲区,并不是直接写入到了文件中
while (1)
{
}
// 关闭文件
fclose(fp);
return 0;
}
总结
| 文件操作函数 |头文件 | 函数原型 |
| -------------|--------------------------------------------| ------------------------------------------------------------|
| fopen() | | FILE* fopen(const char* filename,const char* mode);
| fclose() | | int fclose(FILE * stream);
| fputc() | | int fputc(int ch, FILE * stream);
| fgetc() | | int fgetc(FILE * stream);
| fputs() | | int fputs(const char * str, FILE * stream);
| fgets() | | char * fgets(char * str, int size, FILE * stream);
| fprintf() | | int fprintf(FILE * stream, const char * format, ...);
| fscanf() | #include <stdio.h> | int fscanf(FILE * stream, const char * format, ...);
| fwrite() | | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
| fread() | | size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
| fseek() | | int fseek(FILE *stream, long offset, int whence);
| ftell() | | long ftell(FILE *stream);
| rewind() | | void rewind(FILE *stream);
| remove() | | int remove(const char *pathname);
| rename() | | int rename(const char *oldpath, const char *newpath);
| fflush() | | int fflush(FILE *stream);
------------------------------------------------------------------------------------------------------------------
| stat() | #include <sys/types.h>、 #include <sys/stat.h> | int stat(const char *path, struct stat *buf);