C语言文件操作
文件基础
文件操作: 针对磁盘的文件做一个读写操作
- 标准输入: stdin —>键盘输入
- 标准输出: stdout—>控制台
- 自定义文件: FILE* fp
- 文本文件
- 二进制文件
文本文件
- 1.文件打开
//函数原型
FILE* fopen(const char* fileName,const char* mode);
//filename: 文件路径
//mode: 读写方式
/************************************************************
* w: 只写的方式(write) 创建一个文件进行写入,原文件存在就清空原文件
* r: 只读的方式(read)
* a: 追加模式(append)
* 1.如果存在原文件,就在不清空原文件写操作的情况下,在原文件末位接着写
* 2.如果不存在原文件,创建一个新文件进行写入
*
* +: 代表可读可写
* w+ r+ a+
* b: 二进制的方式
* wb ab rb wb+ ab+ rb+
*************************************************************/
//注意点: C语言打开文件不具备创建文件夹的功能
- 2.文件关闭
- 如果成功关闭文件,fclose( ) 函数返回零,如果关闭文件时发生错误,函数返回 EOF
//函数原型
int fclose(FILE* file)
- 3.文件结束标记: EOF
#include <stdio.h>
int main()
{
FILE* fp=NULL;
fp = fopen("write.txt", "w");
if (fp == NULL)
{
printf("文件打开失败!\n");
return 0;
}
fclose(fp);
fp = fopen("append.txt", "a");
if (fp == NULL)
{
printf("文件打开失败!\n");
return 0;
}
fclose(fp);
fp = fopen("read.txt", "r");
printf("%d\n", EOF);
if (fp == NULL)
{
printf("文件打开失败!\n");
return 0;
}
fclose(fp);
return 0;
}
文件读写
注意点:所有文件操作底层都做了文件指针移动,一般不需要大家手动做文件指针移动(fp++错误)
-
以字符和字符串的方式读写
- 字符的方式
//fgetc(): 读操作
//fputc(): 写操作
int fgetc(FILE* _Stream);
//返回值: 读写的字符
//参数: 文件指针,读的是那个文件
int fputc(int _Character,FILE* _Stream);
//打印的字符是什么:_Character
//打印到哪里: 文件指针指向的文件
#include<stdio.h>
#include<assert.h>
int main ( )
{
FILE* pf = fopen("fp.txt", "w");
assert(pf);
fputc('a', pf);
fclose(pf);//打开一个文件就要关闭一个文件,不然就要等程序结束才会自动关闭
FILE* pf1 = fopen("fp.txt", "r");
assert(pf1);
char x=fgetc(pf1);
printf("%c", x);
fclose(pf1);
return 0;
}
- 字符串的方式
//fgets();
//fputs();
int fputs( char const* _Buffer,FILE* _Stream);
//_Buffer写内容
//_Stream哪个文件
char* fgets(char* _Buffer,int _MaxCount,FILE* _Stream);
//读的内容存到那里: _Buffer
//容器大小: _MaxCount
//从那里开始读的: _Stream
#include<stdio.h>
#include<assert.h>
int main ( )
{
FILE* pf = fopen("fp.txt", "w");
assert(pf);
fputs("helloword", pf);
fclose(pf);
FILE* pf1 = fopen("fp.txt", "r");
assert(pf1);
char x[10];
fgets(x,10,pf1);
printf("%s", x);
fclose(pf1);
return 0;
}
-
格式化读写
格式化读写(表格数据读写)不适用于文件指针移动
int fprintf(FILE* fp,const char* mode,...);
//fp: 打印到文件指针指向文件
//mode: 格式控制字符
//...: 参数名表,多个变量
int fscanf(FILE* fp,const char* mode,...);
//fp: 读的哪个文件
//mode: 按什么格式读
//...: 参数地址表(多个变量的地址)
//注意点:
//1.怎么写怎么读就行了
//2.读操作不支持精度控制
//结构数据的读写
#include <stdio.h>
#include <assert.h>
struct MM
{
char name[20];
int age;
int num;
};
//写操作
void writeFile(struct MM array[], int arrayNum, const char* fileName)
{
FILE* fp = fopen(fileName, "w");
assert(fp);
for (int i = 0; i < arrayNum; i++)
{
fprintf(fp, "%s\t%d\t%d\n", array[i].name, array[i].age, array[i].num);
}
fclose(fp);
}
//读操作
void readFile(const char* fileName)
{
FILE* fp = fopen(fileName, "r");
assert(fp);
struct MM temp[3];
int i = 0;
while (fscanf(fp, "%s\t%d\t%d\n", temp[i].name, &temp[i].age, &temp[i].num) != EOF)
{
fprintf(stdout, "%s\t%d\t%d\n", temp[i].name, temp[i].age, temp[i].num);
//printf("%s\t%d\t%d\n", temp[i].name, temp[i].age, temp[i].num);
i++;
}
fclose(fp);
}
int main()
{
struct MM mm[3] =
{
{"iron",18,1001},
{"Close",16,1002},
{"8K龙",19,1003}
};
writeFile(mm, 3, "fprintf.txt");
readFile("fprintf.txt");
//int a=1;
//fscanf(stdin,"%d",&a); //等效scanf函数
//fprintf(stdout,"%d",a); //等效printf函数
return 0;
}
- 二进制的方式读写
size_t fread( void* buff,size_t size,size_t count,FILE* _Stream);
//读的内容存到那里: buff
//每一次读多少字节: size
//总共读几次: count
//读的哪个文件:_Stream
//注意点: 堆区内存,只能读到char* 内存中
size_t fwrite( void* buff,size_t size,size_t count,FILE* _Stream);
//写的内容: buff
//每一次写多少字节: size
//总共写多少次: count
//写的哪个文件:_Stream
一般用来读结构数据,注意点: 如果写到文件中是乱码大家不要介意,能成功读出来即可
//结构数据的读写
#include <stdio.h>
#include <assert.h>
struct MM
{
char name[20];
int age;
int num;
};
//写操作
void writeFile(struct MM array[], int arrayNum, const char* fileName)
{
FILE* fp = fopen(fileName, "w");
assert(fp);
fwrite(array, sizeof(struct MM), arrayNum, fp);
fclose(fp);
}
//读操作
void readFile(const char* fileName)
{
FILE* fp = fopen(fileName, "r");
assert(fp);
struct MM temp[3];
int i = 0;
fread(temp, sizeof(struct MM), 3, fp);
for (int i = 0; i < 3; i++)
{
printf("%s\t%d\t%d\n", temp[i].name, temp[i].age, temp[i].num);
}
fclose(fp);
}
int main()
{
struct MM mm[3] =
{
{"hh",18,1001},
{"ll",16,1002},
{"xx",19,1003}
};
writeFile(mm, 3, "fprintf.txt");
readFile("fprintf.txt");
return 0;
}
文件指针
void rewind(FILE* file); //把文件指针移动当前文件开头
int fseek(FILE* _Stream,long _Offset, int _Origin); //文件定位
//文件指针:_Stream
//相对位置偏移量:_Offset 正数:右边 负数: 左边
//参照点:_Origin
//SEEK_CUR 当位置
//SEEK_END 结束位置
//SEEK_SET 开始位置
int ftell(FILE* file); //文件指针移动
int feof(FILE* file); //文件是否到达文件末位
文件重定向
FILE* freopen(char const* _FileName,char const* _Mode,FILE* _Stream);
#include <stdio.h>
#include <assert.h>
int main()
{
FILE* fp = freopen("输出文件.txt", "w", stdout);
assert(fp);
FILE* in = freopen("输入文件.txt", "r", stdin);
assert(in);
printf("ILoveyou\n");
int a = 1;
int b = 2;
scanf_s("%d%d", &a, &b); //666 888
printf("%d\n", a + b);
fclose(fp);
fclose(in);
fp = freopen("CON", "w", stdout); //定向到控制台
printf("...........\n");
return 0;
}