我们平时看到的很多文件都是文件,比如txt文本 exe程序等等。C语言中有俩种文件类型,即文本文件和二进制数据文件
文本文件 文本文件又称AscII文件,其中每个字节存放一个ASCII码。文本文件的输出和字符一一对应 每行由零个或多个字符组成,并以'\n'结束。比如数字4567按照文本文件的方式存储 按照字符存储 那么4567占四个字节
二进制数据文件 二进制数据文件是把数据按其在内存中存储的二进制形式以原样存放在磁盘文件中,特点是节省内存。二进制虽然也可以读出来但他无法被人读懂,C语言在处理这些文件时部分类型,都看成是字符流,按字节进行处理 4567的二进制表示是0001000111010111 在内存中占两个字节
C语言中的文件实际上是一种结构体,因此可以用指针来表示。即文件指针,包括文件指针变量和文件类型指针。
我们一般用这个文件指针(指向存放文件信息的结构体变量)访问和操作文件。在C语言中,针对文件设有一个FILE
类型,存放有关文件信息的结构体类型,如下:
typedef struct {
short level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
unsigned char hold; /* Ungetc char if no buffer */
short bsize; /* Buffer size */
unsigned char* buffer; /* Data transfer buffer */
unsigned char* curp; /* Current active pointer */
unsigned istemp; /* Temporary file indicator */
short token; /* Used for validity checking */
} FILE;
可用来定义文件类型指针变量 FILE* fp; 通过文件类型指针变量可以找到与之相关的文件,然后即可进行相关的读/写等操作
C语言在进行文件操作时,必须遵守打开--读写--关闭的流程,不打开就不能读写文件,也必须在使用完成之后关闭文件
C语言提供函数fopen用来打开文件
文件指针名=fopen(文件名,打开文件方式);
文件指针名是FILE类型的指针变量
文件名可以说字符串常量也可以是字符数组
打开文件方式
“r”以只读方式打开一个文件;
“w”以只写方式打开一个文件;
“a”打开一个文件追加;
“rb”以只读方式打开一个二进制文件;
“rw”以只写方式打开一个二进制文件;
“ra”打开一个二进制文件追加;
"r+"以读写方式打开一个文件;
“w+”以读写方式建立一个文件;
“a+”以读写方式打开一个文件追加;
“rb+”以读写方式打开一个二进制文件;
“wb+”以读写方式建立一个二进制文件;
“ab+”以读写方式打开一个二进制文件追加。
例如FILE * fp;
fp = fopen("C.dat","rb");
打开当前目录下的C.dat,以二进制方法读取这个文件 并用文具指针指向这个文件
fp = fopen("C.txt","rt");
以都文本方式打开本目录下的文件,只读
fp = fopen("C.txt","w+t");
在当前目录下创建一个可读写的文本文件
接下来我将说明一些注意事项,可能会在使用过程中出现的问题
用w打开文件表示只写。若文件不存在,则会创建一个文件,若文件存在则会删掉重新创建
若要向文本文件追加新的信息,只能用a方式打开文件。但此时文件必须存在,否则会出错
文件打开模式由r w a t b +六个字符拼成
文本文件需要将ascii转为二进制码,因此文本文件的读写要花费较多的时间
fopen如果打开成功会返回一个FILE指针,如果打开失败会返回一个空指针NULL
使用完文件指针之后应当被关闭,可使用fclose(文件指针),断开与文件的关联 释放被占用的内存空间 同时释放指针变量
C语言提供了许多文件读写的函数,主要区别是读写的单位不同
字符读写函数:fgetc
`fputc`
字符串读写函数:fgets
`fputs`
数据块读写函数:fread
`fwrite`
格式化读写函数:fcanf
`fprinf`
字输入输出函数:getw
`putw`
fputc(字符,文件指针)
顾名思义是将一个字符写入指定的文件中,可以说字符常量也可以是字符变量。写入成功返回写入字符,失败返回EOF
每写入一个字符,文件内部的位置指针向后移动一个字符。文件内部的位置指针用以指示文件内部的读写方式。每读写一次,向后移动,由系统自动设置
字符变量 = fgetc(文件指针)
读取的文件必须是以读或者读写的方式打开,每读出一个字符,文件内的位置指针向后移动一个字符,若读入成功,则返回读入的字符
#include<stdio.h>
#include<stdlib.h>
#pragma warning (disable:4996)
int main()
{
/*从键盘输入字符,以输入'*'为止,逐个存入磁盘文件中,并且再读该文件,将写入
的字符显示到屏幕上*/
FILE* fp;
char filename[50];
char*name = gets_s(filename);
char s[20];
fp = fopen(filename, "wt+");
if (fp ==NULL)
{
printf("error\n");
}
printf("please input the string you want to write\n");
char c = getchar();
while (c!='*')
{
int ret = fputc(c,fp);
c = getchar();
}
fclose(fp);
printf("the file is ");
fp = fopen(filename, "r");
while ((c = fgetc(fp))!= EOF)
{
putchar(c);
}
fclose(fp);
return 0;
}
读字符串函数
fgets(字符数组名,n,文件指针)
从指定的文件中读出一个字符串到字符数组中去
n是正整数,表示从文件中读出的字符串不超过n-1,最后一个字符添加字符串结束标识读取过程中遇到换行符或者结束符号,则读取结束
写字符串函数
fputs(字符串,文件指针)
将一个字符串写入指定文件 这里的字符串可以是字符串常量 字符串指针或者是字符数组
fread
从指定文件读取规定大小的数据块,存入指定的内存缓冲区。调用格式如下:
fread(p,size,n,fp);
p是指要输入输出数据块的首地址的指针
size是数据项的大小,n是从文件中读取的项数,fp是文件指针
fwrite
将一固定长度的数据块写入文件中 fwrite(p,size,n,fp);
函数fread和fwrite在调用成功时候,返回n的值,即输入输出项数,调用失败返回0
#include<stdio.h>
#include<string.h>
#define N 3
#pragma warning (disable:4996)
struct _WORK
{
char name[10];
int ID;
int age;
float salary;
char addr[15];
}worker[N];
char filename[50];
void save();
void diaplay();
int main()
{
for (size_t i = 0; i < N; i++)
{
printf("please input data\n");
printf("name\n");
scanf("%s", &worker[i].name);
printf("ID\n");
scanf("%d", &worker[i].ID);
printf("age\n");
scanf("%d", &worker[i].age);
printf("salary\n");
scanf("%d", &worker[i].salary);
printf("address\n");
scanf("%d", &worker[i].addr);
}
save();
diaplay();
return 0;
}
void save()
{
FILE* fp;
strcpy(filename, "E:\kkk.txt");
if ((fp = fopen(filename,"w")) == NULL)
{
printf("error");
return ;
}
for (size_t i = 0; i < N; i++)
{
if ((fwrite(&worker[i], sizeof(worker[i]), 1, fp))!=1)
{
printf("error");
}
}
fclose(fp);
}
void diaplay()
{
FILE* fp;
if ((fp = fopen(filename, "r"))==NULL)
{
printf("error");
return;
}
for (size_t i = 0; i < N; i++)
{
fread(&worker[i], sizeof(worker[i]), 1, fp);
printf("%s %d %d %f %s\n", worker[i].name, worker[i].ID, worker[i].age, worker[i].salary, worker[i].addr);
}
fclose(fp);
}
文件中的输入输出和数据的输入输出基本类似。文件中的输入输出函数位fprintf和fscanf,他们都是格式化输入输出函数,区别在于读写的对象是磁盘文件而不是键盘和显示器
fcanf(文件指针,格式控制字符串,输入地址列表)
fprintf(文件指针,格式控制字符串,输出列表)
调用成功时,返回输入输出的字节数,调用失败返回EOF
总之以上两个函数,是按照格式对文件进行输出和输入的
#include<stdio.h>
#pragma warning (disable:4996)
int main()
{
char filename[50];
int a = 0;
int b = 0;
char si[50];
char so[50] = {0};
FILE* fp;
gets_s(filename);
if ((fp = fopen(filename,"w"))== NULL)
{
printf("error");
return 0;
}
printf("please input info\n");
scanf("%s", &si);
scanf("%d", &a);
fprintf(fp, "%s %d", si, a);
fclose(fp);
if ((fp = fopen(filename, "r")) == NULL)
{
printf("error");
return 0;
}
fscanf(fp, "%s %d", &so, &b);
printf("%s %d", so, b);
fclose(fp);
}
putw(w,fp)
把字型数据写入文件中
w是四字节数据,可以说变量或者常量
getw
从fp指向的文件中读取一个整型数据
getw(fp);
如果putw和getw调用成功,返回要输入输出的数据,调用失败返回EOF
这个例子我就不写了,写入写出都是四字节。