1、文件的分类:
文件分为两大类,一类是磁盘文件一类是设备文件。
磁盘文件:指一组相关数据的介质,通常存储在外部介质上,使用时才调入内存。
设备文件:在操作系统中把每一个与主机相连的输入、输出设备看做是一个文件,把他们的输入、输出等同于对自盘文件的读和写。
1.1磁盘文件的分类
磁盘文件分为两大类分别是文本文件和二进制文件
文本文件:基于字符编码的文件;基于字符编码,常见编码有ASCII、UNICODE等
一般可以使用文本编辑器直接打开。
二进制文件:基于值编码的文件;自己根据具体应用,指定某个值是什么意思
把内存中的数据按其在内存中的存储形式原样输出到磁盘上。
2、文件的打开和关闭
2.1文件指针file
在C语言中用一个指针变量指向一个文件,这个指针称为文件指针
FILE是系统typedef定义出来的有关文件信息的一种结构体类型,结构中含有
文件名、文件状态和文件当前位置等信息。
#include<stdio.h>
FILE* fopen(const char* filename,const char* mode)
功能:打开文件
参数: filename:需打开的文件名,根据需要添加路径
mode:打开文件的模式设置
返回值: 成功:文件指针
失败:NULL
参数二mode的几种形式:
r或者rb:以只读方式打开一个文本文件(不创建文件,若文件不存在则报错)
w或wb:以写的方式打开(如果文件存在则清空文件,文件不存在则创建一个文件)
a或者ab:以追加的方式打开文件,在末尾添加内容,若文件不存在则创建文件
r+或者rb+:以可读、可写的方式打开文件(不创建新文件)
w+或wb+:以可读、可写的方式打开文件(如果文件存在则清空文件,文件不存在则创建一个文件)
a+或者ab+:以添加方式打开文件,打开文件并在末尾更改文件,若文件不存在则创建文件
打开的文件会占用内存资源,如果总是打开不关闭,会消耗很多内存。
一个进程同时打开的文件数是有限制的,超过最大同时打开文件数,在此调用fopen打开会失败
如果没有明确调用fclose关闭打开的文件,那么程序在退出的时候,操作系统会统一关闭。
#include<>stdio.h
int fclose(FILE * stream);
功能:关闭先前fopen()打开的文件。此动作让缓冲区的数据写入文件中,并释放系统所提供的文件资源
参数: stream:文件指针
返回值: 成功 0
失败 -1
3、文件字符、行读写:
fgetc()、fputc()
①写文件: #include<stdio.h>
int fputc(int ch,FILE * stream);
功能: ch:需要写入文件的字符;
stream:文件指针
返回值: 成功:成功写入文件的字符
失败:返回 -1
③读文件:
#include<stdio.h>
int fgetc(FILE*stream);
功能: 从stream指定的文件中读取一个字符
参数: stream:文件指针
返回值: 成功:返回读取到的字符
失败:-1
②fEOF(): #include<stdio.h>
int feof(FILE*stream);
功能: 检测是否读取到了文件结尾。判断的是最后一次“读操作的内容”,不是当前位置内容
参数: stream:文件指针
返回值: 非0值:已经到文件结尾
0:未到文件结尾
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
int main0201()
{
FILE* fp = fopen("F:/a.txt", "r");
if (!fp)
{
printf("文件打开失败n");
return -1;
}
char ch;
//文件的字符读取
//文件默认结尾为-1
ch = fgetc(fp);
printf("%cn", ch);
//fp++;//err 不能修改文件指针 文件在读取中光标流会自动向下移动
ch = fgetc(fp);
printf("%cn", ch);
ch = fgetc(fp);
printf("%cn", ch);
ch = fgetc(fp);
printf("%cn", ch);
fclose(fp);
return 0;
}
int main0202(void)
{
FILE* fp = fopen("F:/a.txt", "r");//以读的方式打开文件
if (!fp)
{
return -1;
}
char ch;
while ((ch = fgetc(fp))!=EOF)
{
printf("%c", ch);
}
fclose(fp);
}
int main0203(void)
{
//以写的方式打开文件 若文件不存在 会创建一个新文件 若文件存在将清空内容
FILE* fp = fopen("F:/b.txt", "w");
if (!fp)
{
return -1;
}
char ch = 'a';
fputc(ch, fp);
fclose(fp);
return 0;
}
int main0204(void)
{
FILE* fp = ("D:/a.c", "w");
if (!fp)
{
printf("文件打开失败n");
return -1;
}
char ch;
while (1)
{
scanf("%c", &ch);
if (ch == '@')
{
break;
}
fputc(ch, fp);
}
fclose(fp);
return 0;
}
①写文件 fputs
#include<stdio.h>
int fputs(const char* str,FILE* stream);
功能: 将str所指定的字符串写入到stream指定的文件中,字符串结束符‘0’不写入文件。
参数: str:字符串
stream:文件指针
返回值: 成功:0
失败:-1
②读文件 fgets
#include<stdio.h>
char * fgets(char * str , int size , FLIE * stream);
功能:从stream指定的文件内读入字符,保存到str所指定的内存空间,直到出现换行
字符、读到文件结尾或已读了size-1个字符为止,最后会自动加上字符‘0’作为字符串结束
参数: str:字符串
size:指定最大读取字符串的长度(size-1)
stream:文件指针,如果键盘输入的字符串,固定写为stdin
返回值: 成功:成功读取的字符串
读到文件尾或出错:NULL
四则运算练习
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
enum opt//枚举
{
add,sub,mlt,dive
};
int main05()
{
srand((size_t)time(NULL));//添加随机数种子
FILE* fp = fopen("F:/四则运算.txt", "w");
if (!fp)
return -1;
int a, b;
char c;
char* p = (char*)malloc(sizeof(char) * 20);
for (int i = 0; i < 100; i++)
{
a = rand()%10 + 1;// %10随机的数字是0~9 再+1是1~10
b = rand() % 10 + 1;
switch (rand()%4)
{
case add:c = '+';break;
case sub:c = '-';break;
case mlt: c = '*';break;
case dive: c= '/';break;
}
memset(p, 0, 20);
sprintf(p, "%d%c%d=n", a, c,b);
fputs(p, fp);
}
free(p);
fclose(fp);
//p = NULL;
//fp = NULL;
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
int main06()
{
FILE* fp1 = fopen("F:/四则运算.txt", "r");
FILE* fp2 = fopen("F:/四则运算结果.txt", "w");
if (!fp1 || !fp2)
{
printf("打开文件失败n");
return -1;
}
//!feof(fp);文本文件和二进制文件均可判断是否为结尾 EOF仅用于文本文件
int a, b, sum;
char c;
char* p = (char*)malloc(sizeof(char) * 20);
for (int i = 0; i < 100; i++)
{
memset(p, 0, 20);
fgets(p, 20, fp1);
sscanf(p,"%d%c%d=n", &a, &c, &b);
switch (c)
{
case'+':sum = a + b; break;
case'-':sum = a - b; break;
case'*':sum = a * b; break;
case'/':sum = a / b; break;
}
memset(p, 0, 20);
sprintf(p, "%d%c%d=%dn", a, c, b, sum);
fputs(p, fp2);
}
free(p);
fclose(fp1);
fclose(fp2);
return 0;
}
4、文件格式化读写
fprintf()、fscanf()
①写文件 fprintf()
#include<stdio.h>
int fprintf(FILE*stream,const char *format,...);
功能: 根据参数format字符串来转换并格式化数据,然后将结果输出到stream指定文件中,指定
出现字符串结束符‘0’为止
参数: stream:已打开的文件
format:字符串格式,用法和printf()一样
返回值: 成功:实际写入文件的字符个数
失败:-1
②读文件 fscanf()
#include<stdio.h>
int fscanf(FILE * stream,const char * format,...);
功能: 从stream指定的文件读取字符串,并根据参数format字符串来转换并格式化数据。
参数: stream:已打开的文件
format:字符串格式,用法和scanf()一样
返回值: 成功:参数数目,成功转换的值的个数
失败:-1
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
int main0701()//fscanf()从文件中获取写入数据
{
FILE* fp = fopen("F:/a.txt", "r");
if (!fp)
return -1;
char* p = (char*)malloc(sizeof(char) * 100);
int a;
fscanf(fp, "%d", &a);
printf("%dn",a);
fscanf(fp, "%s", p);
printf("%s", p);
fclose(fp);
free(p);
return 0;
}
int main0702(void)
{
FILE* fp = fopen("F:/b.txt", "r");
if (!fp)
return -1;
//int a, b, c;
//fscanf(fp, "%d+%d=%d", &a, &b, &c);
//char ch[20] = {0};//初始化为0
//memset(fp,0,20);//同上初始化
//fscanf(fp, "%[^n]", ch);//正则表达式 读取到空格
//fscanf(fp, "%11c", ch);
//printf("%sn", ch);
//printf("%dn%dn%dn", a, b, c);
int a;
fscanf(fp, "%x", &a);
printf("%dn", a);
fclose(fp);
return 0;
}
int main0703(void)
{
FILE* fp = fopen("f:/b.txt", "w");
if (!fp)
return -1;
//char ch[] = "hello world";
//fprintf(fp, "%s", ch);
int a = 10;
fprintf(fp, "%05x", a);
fclose(fp);
}
int main0704(void)
{
srand((size_t)time(NULL));
FILE* fp = fopen("f:/四则运算.txt", "w");
if (!fp)
return -1;
int a, b;
char c;
for (int i = 0; i < 100; i++)
{
a = rand() % 10 + 1;
b = rand() % 10 + 1;
switch (rand()%4)//rand()%4 随机0~3的数字
{
case 0:c = '+'; break;
case 1:c = '-'; break;
case 2:c = '*'; break;
case 3:c = '/'; break;
}
fprintf(fp, "%d%c%d=n", a, c, b);
}
fclose(fp);
}
int main0705(void)
{
FILE* fp1 = fopen("F:/四则运算.txt","r");
FILE* fp2 = fopen("F:/四则运算结果.txt","w");
if (!fp1 || !fp2)
{
printf("文件打开失败n");
return -1;
}
int a, b,sum;
char c;
for (int i = 0; i < 100; i++)
{
fscanf(fp1, "%d%c%d=n", &a, &c, &b);
switch (c)
{
case'+':sum = a + b; break;
case'-':sum = a - b; break;
case'*':sum = a * b; break;
case'/':sum = a / b; break;
}
fprintf(fp2, "%d%c%d=%dn", a, c, b, sum);
}
fclose(fp1);
fclose(fp2);
}
大文件排序:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
int main08()
{
srand((size_t)time(NULL));
FILE* fp = fopen("f:/数据.txt", "w");
if (!fp)
return -1;
for (int i = 0; i < 1000; i++)
{
fprintf(fp, "%dn", rand() % 256);
}
fclose(fp);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
void Bubble_Sort(int * arr, int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main0901()
{
FILE* fp1 = fopen("F:/数据.txt", "r");
FILE* fp2= fopen("F:/数据冒泡排序版.txt", "w");
if (!fp1 || !fp2);
return -1;
//冒泡排序法
int* arr = (int*)malloc(sizeof(int) * 1000);
for (int i = 0; i < 1000; i++)
{
fscanf(fp1, "%dn", &arr[i]);
}
Bubble_Sort(arr, 1000);
for (int i = 0; i < 1000; i++)
{
fprintf(fp2, "%dn", arr[i]);
}
free(arr);
fclose(fp1);
fclose(fp2);
return 0;
}
int main0902()
{
FILE* fp1 = fopen("F:/数据.txt", "r");
FILE* fp2 = fopen("F:/数据插入版.txt", "w");
if (!fp1 || !fp2);
return -1;
int* arr = (int*)malloc(sizeof(int) * 256);
memset(arr, 0, sizeof(int) * 256);
for (int i = 0; i < 1000; i++)
{
int value;
fscanf(fp1, "%dn", &value);
arr[value]++;//将数据的个数放在队形的下标里
}
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < arr[i]; j++)
{
fprintf(fp2, "%dn", i);
}
}
free(arr);
fclose(fp1);
fclose(fp2);
}
5、文件块读写
fread()、fwrite()
①写文件 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
②读文件 fread
#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
返回值: 成功:实际成功读取到内容的块数,蜀国此值比nmemb小,
但大于0,说明读到文件结尾
失败:0
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
int main10_01()//fwrite(写入文件地址,sizeof(类型),元素个数,写入文件指针)函数
{
FILE* fp = fopen("F:/c.txt", "wb");
if (!fp)
return -1;
//int a = 5678;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
fwrite(arr, sizeof(int), 10, fp);
fclose(fp);
return 0;
}
int main10_02(void)//fread()函数
{
FILE* fp = fopen("f:/c.txt", "rb");
if(!fp)
return -1;
//int value;
//fread(&value, sizeof(int), 1, fp);
int arr[10] = { 0 };
fread(arr, sizeof(int), 10, fp);
for (int i = 0; i < 10; i++)
{
printf("%dn", arr[i]);
}
fclose(fp);
return 0;
}
6、文件读写结构体
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
typedef struct student
{
char name[21];
int age;
int score;
char addr[51];
}stu;
int main11_01()
{
stu ss[3] =
{
{"陈胜",22,10,"北京市"},
{"吴广",25,15,"昌平"},
{"胡海",15,20,"海淀"},
};
FILE* fp = fopen("d:/d.txt", "wb");
if (!fp)return -1;
for (int i = 0; i < 3; i++)
{
fwrite(&ss[i], sizeof(stu), 1, fp);
}
fclose(fp);
return 0;
}
int main(void)
{
FILE* fp = fopen("d:/d.txt", "rb");
if (!fp)return -1;
stu* ss = (stu*)malloc(sizeof(stu) * 3);
int i = 0;
while (!feof(fp))
{
fread(&ss[i], sizeof(stu), 1, fp);
i++;
}
for (int i = 0; i < 3; i++)
{
printf("姓名:%sn", ss[i].name);
printf("年龄:%dn", ss[i].age);
printf("分数:%dn", ss[i].score);
printf("地址:%sn", ss[i].addr);
}
free(ss);
fclose(fp);
return 0;
}
//文件的随机读写
#include<stdio.h>
int fseek(FILE * stream , long offset , int whence);
功能: 移动文件流(文件光标)的读写位置
参数: stream:已经打开的文件指针
offset:根据whence来移动的位移数(偏移量),可以是正数,也可以是负数,如果是正数
则上对于whence往右移,如果是负数,则相对于whence往左移。如果向前移的字节数超过
了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再此写入时将增大文件尺寸。
whence:其取值如下:
SEEK_SET:从文件开头移动offse个字节
SEEK_CUR:从当前位置移动offset个字节
SEEK_END:从文件末尾移动offset个字节
返回值: 成功:0
失败:-1
7、获取文件状态
①stat
#include<sys/types.h>
#include<sys/stat.h>
int stat(const char * path , struct stat * buf);
功能: path:文件名
buf:保存文件信息的结构体
返回值: 成功:0
失败:-1
②ftell
#include<stdio.h>
long ftell(FILE * stream);
功能: stream:已经打开的文件指针
返回值: 成功:当前文件流(文件光标)的读写位置
失败:-1
③rewind
#include<stdio.h>
void rewind(FILE * stream)
功能: 把文件流(光标流)的读写位置移动到文件开头
参数: stream:已经打开的文件指针
返回值: 无返回值
8、删除文件、重命名文件名
①remove
#include<stdio.h>
int remove(const char * pathname);
功能: 删除文件
参数: pathname:文件名
返回值: 成功:0
失败:-1
②rename
#include<stdio.h>
int rename(const char * oldpath,const char * newpath);
功能: 把oldpath的文件名改为newpath
参数: oldpath:旧文件名
newpath:新文件名
返回值: 成功:0
失败:-1
最新评论