什么是文件
磁盘上的文件是文件;文件包含文件内容和文件属性,都是数据,需要保存;文件分为程序文件(源程序文件、目标文件、可执行程序文件)和数据文件
文件类型
数据文件分为文本文件(以ASCII码的形式存储)和二进制文件(以为二进制的形式存储)
文件缓冲区
1、从内存向磁盘输入数据会先送到内存中的缓冲区,装满缓冲区之后才一起送到磁盘上(输出);从磁盘上读取数据输入到内存缓冲区,充满缓冲区之后,再从缓冲区逐个地将数据送到程序数据区(输入)。
2、内存中三种缓冲方式
(1)无缓冲 直接显示有数据输出,提高效率
(2)行缓冲 以'\n'结尾或写满,刷新到显示器上
(3)全缓冲 把内存写满,统一刷新
文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字、状态、当前位置等)。这些新鞋是保存在一个结构体变量中的,该结构体类型是由系统声明的,取名FILE。
FILE* pf;//文件指针变量
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区,通过该文件信息区中的信息就能够访问该文件。
文件的打开和关闭
文件名:文件路径+文件主干+文件后缀

例如:c:\use\test.txt
fopen函数打开文件
FILE* fopen(const char* filename,const char* code);
第一个参数为文件名,第二个参数为打开文件的方式;
打开文件成功,则返回文件指针;打开文件失败,则返回空指针NULL
fclose函数关闭文件
int fclose(FILE* stream);
参数为文件指针;
关闭成功时,返回0;关闭失败时,返回一个非零值
文件的打开方式:
“r”只读 为了输入数据,打开一个已经存在的文本文件;如果指定文件不存在,则出错
“w”只写 为了输入数据,打开一个文本文件;如果存在同名文件,则原内容会被清空;如果指定文件不存在,则建立一个新的文件
“a”追加 向文本文件尾添加数据;如果指定文件不存在,则创建一个
“rb”只读 为了输入数据,打开一个已经存在的二进制文件;如果指定文件不存在,则出错
“wb”只写 为了输入数据,打开一个二进制文件;如果存在同名文件,则原内容会被清空;如果指定文件不存在,则建立一个新的文件
“ab”追加 向二进制文件尾添加数据;如果指定文件不存在,则创建一个
“r+”读写 为了读和写,打开一个已经存在的文本文件;如果指定文件不存在,则出错
“w+”读写 为了读和写,打开一个文本文件;如果存在同名文件,则原内容会被清空;如果指定文件不存在,则建立一个新的文件
“a+”读写 打开一个文本文件,在文件尾进行读和写;如果指定文件不存在,则建立一个新的文件
“rb+”读写 为了读和写,打开一个已经存在的二进制文件;如果指定文件不存在,则出错
“wb+”读写 为了读和写,打开一个二进制文件;如果存在同名文件,则原内容会被清空;如果指定文件不存在,则建立一个新的文件
“ab+”读写 打开一个二进制文件,在文件尾进行读和写;如果指定文件不存在,则建立一个新的文件
#include <stdio.h>
int main()
{
FILE* pfile;
pfile=fopen("myfile.txt", "r");//"w" “a”时打开文件成功
if (pfile != NULL)
{
printf("打开文件成功\n");
fclose(pfile);
}
else
{
printf("打开文件失败\n");//"r"只读的形式打开文本文件,因为该文件不存在,所以打开失败
}
system("pause");
return 0;
}
文件的顺序读写
1.文件的顺序写操作函数
fprintf()/fputs()/fputc()
(1)int fprintf(FILE* stream,char* format,<variable-list>);
返回值为实际写入文件中的字节数;如果写入失败,则返回一个负数
(2)int fputs(char* string,FILE* stream);
将string指针所指向的字符串写入到文件中;操作成功时,返回值为0;操作失败时,返回一个非0数
(3)int fputc(int ch,FILE* stream);
向文件写入一个字符;操作成功时,返回项文件所写字符的值;失败时,返回EOF(-1)
#include <stdio.h>
int main()
{
char *s = "renhao is cool boy"; /*定义字符串指针并初始化*/
int i = 717; /*定义整型变量并初始化*/
FILE *fp; /*定义文件指针*/
fp = fopen("test.txt", "w"); /*建立一个文字文件只写*/
fputs("renhao and heluoluo", fp);/*向所建文件写入一串字符*/
fputc(':', fp); /*向所建文件写冒号:*/
fprintf(fp, "%d\n", i); /*向所建文件写一整型数*/
fprintf(fp, "%s", s); /*向所建文件写一字符串*/
fclose(fp); /*关闭文件*/
system("pause");
return 0;
}
2.文件的顺序读操作函数
fscanf()/fgets()/fgetc()
(1)int fscanf(FILE* stream,char* format,<address-list>);
第一个参数为要读取的文件的文件指针,基本上和scanf()函数的用法一致;
(2)char fgets(char* string,int n,FILE* stream);
从文件中读取n-1个字符(n用来指定字符数),把它们放入string指向的字符串中,读入之后自动向字符串末尾加一个空字符,读成功返回string指针,失败则返回一个空指针;
(3)int getc(FILE* stream);
返回文件当前位置的第一个字符,读错误时返回EOF;
#include <stdio.h>
int main()
{
char *s=NULL, m[20];
int i;
FILE *fp;
fp = fopen("test.txt", "r"); /*打开文字文件只读*/
fscanf(fp, "%d", &i); /*读取整型数*/
printf("%d", i); /*输出所读整型数*/
putchar(fgetc(fp)); /*读取一个字符同时输出*/
fgets(m, 17, fp); /*读取16个字符*/
puts(m); /*输出所读字符串*/
fclose(fp); /*关闭文件*/
system("pause");
return 0;
}
文件的随机读写
1.fseek函数:根据文件指针的位置和偏移量来定位文件指针
int fseek(FILE* stream,long offset,int frowwhere);
将文件的位置指针设置从fromwhere开始的offset字节上;
fromwhere是下列几个宏定义之一:
符号常数 数值 含义 SEEK_SET 0 文件开始 SEEK_CUR 1 文件指针的当前位置 SEEK_END 2 文件结尾*
2.ftell函数
返回文件指针相对于起始位置的偏移量
long int ftell(FILE* stream);
#include <stdio.h>
int main()
{
FILE* pfile;
pfile = fopen("test.txt", "wb");
fputs("this is pen", pfile);//写入
fseek(pfile, 9, SEEK_SET);//读取 将文件的指针从seek_set的位置偏移9个位置
fputs("sam", pfile);//this is psam
int size=ftell(pfile);//当前文件指针相对于文件的起始位置的偏移量 12
printf("%d\n", size);
fclose(pfile);
system("pause");
return 0;
}
3.rewind函数
让文件指针的位置回到文件的起始位置
void rewind(FILE* stream);
写入位置改为0,会覆盖之前写的内容
#include <stdio.h>
int main()
{
int n;
FILE* pfile;
char buffer[27];
pfile = fopen("myfile.txt", "w+");
for (n = 'A'; n <= 'Z'; n++)
{
fputc(n, pfile);//写入
}
rewind(pfile);
fputc(':', pfile);
fclose(pfile);
system("pause");
return 0;
}
文件结束的判定
在文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
(1)文本文件读取是否结束,判断返回值是否为EOF(fgetc)或者为NULL(fegts);
#include <stdio .h>
int main()
{
int c;
FILE* fp = fopen("test.txt", "r");
if (!fp)
{
perror("File opening failed");
return EXIT_FAILURE;
}
//fegtc 当读取失败时或者遇到文件结束时,都会返回EOF
while ((c = fgetc(fp)) != EOF)
{
putchar(c);
}
//判断是什么原因结束的
if (ferror(fp))
{
puts("I/O error when reading ");
}
else if (feof(fp))
{
puts(" End of file reached successfully");
}
system("pause");
return 0;
}
(2)二进制文件读取的结束,判断返回值是否小于实际要读的个数;(fread判断返回值是否小于实际要读的个数)
fread 二进制的输入:
size_t fread(void *buffer,size_t num_bytes,size_t count,FILE *fp);
buffer是接收读入数据的内存区的指针;
count的值确定读/写多少项,每项长度等于num_bytes。
fwrite 二进制的输出:
size_t fwrite(const void *buffer,size_t num_bytes,size_t count,FILE *fp);
buffer是写入到那个文件的信息的指针。
#include <stdio.h>
enum{
size = 5
};
int main()
{
double arry[size] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
double num = 0.0;
size_t ret_code = 0;
FILE* fp = fopen("test_two.txt", "wb");//二进制
//二进制输出 写
fwrite(arry, sizeof(*arry), size, fp);
fclose(fp);
fp = fopen("test_two.txt", "rb");
//读文件
while ((ret_code=fread(&num,sizeof(double),1,fp))>=1)
{
printf("%1f\n", num);
}
//判断是什么原因结束的
if (ferror(fp))
{
printf("error reading test.bin\n");
}
else if (feof(fp))
{
printf("unexpected end of file\n");
}
system("pause");
return 0;
}