我们经常见到的文件写入和读取。
#include<iostream>
using namespace std;
typedef struct
{
char no[10];
char name[10];
double foreign;
double spec1;
double spec2;
double total;
}StudentType;
void WriteToFile();
void ReadFromFile();
int main()
{
int select;
do
{
printf("1:录入成绩2:输出成绩 0:退出\n");
printf("请输入要执行的操作");
cin >> select;
switch (select)
{
case 1:
WriteToFile();
break;
case 2:
ReadFromFile();
break;
default:
cout << "退出程序" << endl;
break;
}
} while ((select == 1 || select == 2));
system("pause");
return 0;
}
void WriteToFile()
{
FILE *fp = NULL;
StudentType stu;
char flag = 'y';
fp = fopen("student.txt", "a");//append 以追加的方式打开文件
if (fp == NULL)
{
printf("打开文件失败");
exit(1);//以有错的方式退出程序
}
while (flag == 'y' || flag == 'Y')
{
printf("请输入考生考号:\n");
scanf("%s", stu.no);
printf("请输入考生姓名\n");
scanf("%s", stu.name);
printf("请输入学生的外语成绩:\n");
scanf("%lf", &stu.foreign);
printf("请输入考生的专业课一成绩:\n");
scanf("%lf", &stu.spec1);
printf("请输入考生的专业课二成绩:\n");
scanf("%lf", &stu.spec2);
stu.total = stu.foreign + stu.spec1 + stu.spec2;
fprintf(fp, "%10s%10s%8.2f", stu.no, stu.name, stu.foreign);
fprintf(fp, "%8.2f%8.2f%8.2f", stu.spec1, stu.spec2, stu.total);
fputc('\n', fp);
fflush(stdin);//将键盘输入的信息(缓冲区中的信息)刷新一下
printf("继续输入吗?继续请输入Y或者y");
scanf("%c", &flag);
}
fclose(fp);
return;
}
void ReadFromFile()
{
FILE* fp = NULL;
StudentType stu;
fp = fopen("student.txt", "r");
if (fp == NULL)
{
printf("打开文件失败");
exit(1);
}
printf(" 考试姓名 总分\n");
while (!feof(fp))//当没有遇见文件结束符的时候
{
fscanf(fp, "%s %s", stu.no, stu.name);
fscanf(fp, "%lf%lf%lf%lf", &stu.foreign, &stu.spec1, &stu.spec2, &stu.total);
printf("%10s%8.2f\n", stu.name, stu.total);
}
fclose(fp);
return;
}
文件是个结构体类型,这个结构体成员有
struct _iobuf {
char *ptr; //文件当前位置
int _cnt;
char* _base;//缓冲区首地址
int _flag;
int _file;//文件号
int char_buf;
int _bufsize;//缓冲区长度
char *_temfname;
}_iobuf;
typedef struct _iobuf FILE;
C语言中文件是流式文件,文件是由一个一个的字节组成,文本文件每个字节对应一个字符,对于二进制文件,每个字节对应一个二进制位串。
文件指针一般打开方式下,位置指针设置在文件头
追加打开方式下,位置指针设置在文件尾
ftell函数 feof函数检测文件的当前位置指针
操作成功返回filepointer文件的当前位置指针,即相对于文件开头的位移量(字节数)。否则返回-1L(L表示该常量为长整型)
feof函数测试是不是在文件末尾
long int n;
n = ftell(fp);
ftell函数可以这么使用来观察相对于首位的偏移量。
定义文件当前位置指针
fseek函数 rewind函数 改变文件当前位置指针
void rewind(FILE filepointer)
int fseek(FILE filepointer,long offset,int origin)
offset是指针偏移量,origin是起始位置
操作成功就返回0,不成功返回非0
需要注意origin
SEEK_CUR 1 文件当前位置
SEEK_END 2 文件末尾
SEEK_SET 0 文件开头
offset可以为正可以为负
打开文件函数
fopen();
FILE* fopen(char* filename,char* mode)//分别代表 打开文件名 打开文件方式
文件类型:
b(binary) 打开一个二进制文件
t(text) 打开一个文本文件
文件打开方式
在文件开始
r(read) //只读方式打开一个已经存在的文件
r+(read and write) //打开文件准备读写
w//只写 如果文件已经存在则覆盖原文件
w+//创建一个新文件准备读写,如果文件不存在,创建这个文件准备写数据
在文件末尾
a//以追加方式打开一个已经存在文件,不能从文件读取数据,如果文件不存在,则创建这个文件准备写数据
a+//打开一个文件准备读写,不存在则创建该文件
文件关闭
fclose函数
int fclose(FILE* filepointer).
文件读写操作:
int fputc(int c,FILE *filepointer)
c是要写入的字符,该函数向filepointer文件的当前位置写入一个ASCLL码为c的字符,同时将文件的位置指针指向下一个字节,写入成功则返回写入字节值,否则返回EOF(-1)
char* fgets(char* str, int n, FILE *filepointer);
str 是读出的字符串 n是读取的长度 n-1 (0~n-1),filepointer从这个文件读字符串。
从filepointer文件的当前位置读取长度为n-1的字节串,在末尾加上字符串终结符‘\0’存入str所指向的内存单元,同时将文件的位置指针后移n-1个字节。
读取成功,返回指向字符串的指针,如果读到文件尾或者出错返回NULL。
char str[80];
fgets(str, 15, fp);
来看代码
这个代码代表意思是从fp所指向的文件中读取14个字符出来,放入str中,后面再填充‘\0’,凑齐15个字符。
格式化的方式读写:
fscanf fprintf
不同点在于这两个函数规定了格式要求
例如:
fscanf(fp, "%s %s", stu.no, stu.name);
二进制当时进行文件读写
fread 和 fwrite函数
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
buffer是数据存储位置, size是数据所占字节数, n是写入n个数据 filepointer是从这个文件读。
fwrite和这个一样
我们来看几个程序的实例
如何将一个文件的内容拷贝到另一个文件中
void copy(char fileS[], char fileT[])
{
char ch;
FILE *fpSource, *fpTarget;
if ((fpSource = fopen(fileS, "r")) == NULL)
{
printf("打开失败\n");
exit(1);
}
if ((fpTarget = fopen(fileT, "w")) == NULL)
{
printf("打开失败\n");
exit(1);
}
while (!feof(fpSource))
{
ch = fgetc(fpSource);
fputc(ch, fpTarget);
}
fclose(fpSource);
fclose(fpTarget);
printf("文件复制成功");
}
来看一下二进制文件的写入
void saveToFile(struct studentType stud[], int num)
{
FILE * fp;
int i;
if ((fp = fopen("stu.dat", "wb")) == NULL)
{
printf("cannot open file");
return;
}
for (i = 0; i < num; i++)
{
if (fwrite(&stud[i], sizeof(struct studentType), 1, fp) != 1)
{
printf("file write error\n");
}
}
fclose(fp);
}
再来看二进制文件的读取
void readFromFile()
{
struct studentType stud[];
int i;
FILE* fp;
if ((fp = fopen("stu.dat", "rb")) == NULL)
{
printf("cannot open file");
return ;
}
while (!feof(fp))
{
if (fread(&student, sizeof(struct studentType), 1, fp) == 1)
{
printf("%-10s%4d,%4d%-15s\n", student.name, student.num, student.age, student.addr);
}
}
fclose fp;
}
以下就是文件的基本使用