【C】 一篇文章搞定C语言文件操作(巨细致)

什么是文件?

“文件”一词最早在1952年用于计算机数据方面,指的是在打孔卡上所储存的信息。

计算机文件(或称文件、电脑档案、档案),是存储在某种长期储存设备上的一段数据流
长期储存设备”一般指磁盘、光盘、磁带等。
特点是所存信息可以长期、多次使用,不会因为断电而消失。

什么是文件名?

计算机文件名由 基本名扩展名 构成,基本名和扩展名之间使用 . 分割开
基本名是给人看的,让计算机使用者明白这个文件内容是关于什么的。
扩展名是给计算机看的,让计算机明白这个文件中的数据应该以什么格式来保存。

图解
在这里插入图片描述

文件有哪些类型?

程序设计中根据数据的组织形式文件类型:
1.文本文件:以ASCII码字符的形式存储的文件
2.二进制文件:数据在内存中以二进制的形式存储,不加转换输出保存到外存,产生的文件就是二进制文件

在这里插入图片描述

文件缓冲区

数据从 内存 存入 外存 图解
在这里插入图片描述

ANSI标准采用缓冲文件系统处理数据文件
缓冲文件系统指系统自动为程序中每一个正在使用的文件开辟一块文件缓冲区
文件缓冲区大小由C编译器决定
内存->外存:数据先从内存流入输出缓冲区,装满缓冲区后再一起流入外存
外存->内存:数据从外存读入输入缓冲区,装满缓冲区后再一起流入内存

文件指针

缓冲文件系统中最重要的概念就是文件类型指针,简称文件指针
文件信息区:每一个被使用的文件在内存中开辟了一个用于存放文件相关信息的区域。
文件信息区是一个结构体,名字叫FILE
不同的C编译器,文件信息区存储的文件信息不尽相同,但是基本大同小异
每打开一个文件时,系统会根据文件的情况自动创建一个FILE结构体变量,并自动向其中填充文件相关信息

FILE源码

struct _iobuf {
    
    
	char *_ptr;
	int   _cnt;
	char *_base;
	int   _flag;
	int   _file;
	int   _charbuf;
	int   _bufsiz;
	char *_tmpfname;
};
typedef struct _iobuf FILE;

一般使用者都是通过文件指针变量来访问操作文件

FILE* pf;	//文件指针变量

文件指针图解
在这里插入图片描述

文件的打开与关闭

文件使用前需要打开文件,在使用结束后需要关闭文件
在编写C语言程序打开文件时,都会返回一个FILE指针变量指向该文件,也相当于通过指针就可以间接访问文件内容
ANSIC规定使用fopen函数来打开文件,使用fclose函数关闭文件

fopen函数

FILE * fopen ( const char * filename, const char * mode );
filename是文件的路径
mode是打开文件的方式
返回值:打开成功返回一个指向该文件对象的指针;如果打开失败返回一个空指针

打开方式
在这里插入图片描述

fclose函数

int fclose ( FILE * stream );
如果流成功关闭则返回0,失败时返回EOF(-1)

测试程序

程序说明:以w(只写)的打开方式打开TestFILE.txt文件,如果没有此文件则新建名为TestFILE.txt文件

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("TestFile.txt","w");
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!");
	fclose(pf);
	return 0;
} 

执行程序结果
在这里插入图片描述
在这里插入图片描述

文件的顺序读写

字符输入输出

fputc函数

int fputc ( int character, FILE * stream );
将字符写入文件
返回值:写入成功时返回字符的ASCII码值;写入失败时返回EOF

测试程序

程序说明:将TestFile.txt文件以w(只写)的方式打开,将ASCII码值为100的字符写入TestFile.txt文件中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("TestFile.txt","w");
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	int c  = 100;
	int d = fputc(c,pf);
	printf("字符%c的ASCII码值为:%d\n",d,c);
	
	fclose(pf);
	return 0;
} 

程序运行结果
在这里插入图片描述在这里插入图片描述

fgetc函数

int fgetc ( FILE * stream );
从文件中读取字符
返回值:读取成功时返回字符的ASCII码值;读取失败时返回EOF

测试程序

程序说明:将TestFile.txt文件以r(只读)的方式打开,将文件中第一个字符读取出来,将其ASCII码值放入整形变量d中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("TestFile.txt","r");
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	int d = fgetc(pf);
	printf("字符%c的ASCII码值为:%d\n",d,d);
	
	fclose(pf);
	return 0;
} 

程序运行结果
在这里插入图片描述在这里插入图片描述

字符串输入输出

fputs函数

int fputs ( const char * str, FILE* stream );
作用:将字符串写入文件中
返回值:写入成功返回非负值;写入失败返回EOF

测试程序

程序说明:将TestFile.txt文件以w(只写)的方式打开,将字符串写入文件中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("TestFile.txt","w");
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	const char *s = "Hello World!\n";
	int c = fputs(s,pf);
	
	if(c != EOF){
    
    
		printf("写入成功!\n");
	}else{
    
    
		printf("写入失败!\n");
	}
	
	fclose(pf);
	return 0;
} 

程序运行结果
在这里插入图片描述在这里插入图片描述

fgets函数

char * fgets ( char * str, int num, FILE * stream );
作用:将文件中前num个字符读取出来写入字符串中
返回值:写入成功,返回由读取的内容形成的字符串;写入失败,返回空指针

测试程序

程序说明:将TestFile.txt文件以r(只读)的方式打开,将字符串从文件写入字符数组中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("TestFile.txt","r");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	char s[100];
	char *s_copy = fgets(s,20,pf);
	
	if(s_copy != NULL){
    
    
		printf("读取成功!\n");
		printf("取出的字符串为:%s\n",s); 
	}else{
    
    
		printf("读取失败!\n");
	}
	
	fclose(pf);
	return 0;
} 

程序运行结果
在这里插入图片描述

格式化输入输出

fprintf函数

int fprintf ( FILE * stream, const char * format, … );
作用:将格式字符串写入文件
返回值:写入成功时,返回写入的字符总数;写入失败时,返回负值

测试程序

程序说明:将TestFile.txt文件以w(只写)的方式打开,将格式字符串写入文件中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("TestFile.txt","w");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	char *s = "你好,我叫XXX!\n";
	
	int flag = fprintf(pf,"%s",s);
	
	if(flag >= 0){
    
    
		printf("写入成功!\n");
	}else{
    
    
		printf("写入失败!\n");
	}
	
	fclose(pf);
	return 0;
} 

程序运行结果
在这里插入图片描述在这里插入图片描述

fscanf函数

int fscanf ( FILE * stream, const char * format, … );
作用:将文件中的数据按照格式字符串读出
返回值:

测试程序

将TestFile.txt文件以r(只读)的方式打开,将文件中的数据以格式字符串的形式放入字符数组中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("TestFile.txt","r");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	char s[100];
	
	int flag = fscanf(pf,"%s",&s);
	
	if(flag >= 0){
    
    
		printf("读取成功!\n");
		printf("读取的格式化字符串为:%s",s);
	}else{
    
    
		printf("读取失败!\n");
	}
	
	fclose(pf);
	return 0;
} 

程序运行结果

在这里插入图片描述

二进制输入输出

fwrite函数

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
作用:Write block of data to stream,Writes an array of count elements, each one with a size of size bytes, from the block of memory pointed by ptr to the current position in the stream.

测试程序1

程序说明:以wb(只写)打开或新建BinaryDatas二进制文件,将一个整形数据以二进制方式写入文件中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("BinaryDatas","wb");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	int s = 100;
	
	int flag = fwrite(&s,sizeof(int),1,pf);
	
	if(flag >= 0){
    
    
		printf("写入成功!\n");
	}else{
    
    
		printf("写入失败!\n");
	}
	
	fclose(pf);
	return 0;
} 

程序1运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试程序2

程序说明:以wb(只写)打开或新建myfile.bin二进制文件,将一个字符数组数据以二进制方式写入文件中

#include <stdio.h>
int main ()
{
    
    
  FILE * pFile;
  char buffer[] = {
    
     'x' , 'y' , 'z' };
  pFile = fopen ("myfile.bin", "wb");
  fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
  fclose (pFile);
  return 0;
}

程序2运行结果
在这里插入图片描述

fread函数

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
作用:Read block of data from stream,Reads an array of count elements, each one with a size of size bytes, from the stream and stores them in the block of memory specified by ptr.

测试程序

程序说明:以rb(只读)打开BinaryDatas二进制文件,将一个整形数据以二进制方式从文件中读取出来放入整形变量中

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("BinaryDatas","rb");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	int s;
	
	int flag = fread(&s,sizeof(int),1,pf);
	
	if(flag >= 0){
    
    
		printf("读取成功!\n");
		printf("读取的数据为:%d\n",s);
	}else{
    
    
		printf("读取失败!\n");
	}
	
	fclose(pf);
	return 0;
} 

程序运行结果

在这里插入图片描述

文件的随机读写

fseek函数

int fseek ( FILE * stream, long int offset, int origin );
参数:offset是偏移量;origin是起始位置
作用:重新定位文件指针指向从 origin开始 偏移offset个字符 数据的位置
返回值:定位成功返回0;定位失败返回非0值

origin可取的值

在这里插入图片描述

测试程序

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("BinaryDatas","wb");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	fputs ( "This is an apple." , pf );	//向文件中写入 This is an apple.
	fseek ( pf , 9 , SEEK_SET );		//将指针定位在字符n出,
	fputs ( " sam" , pf );	//写入 sam这四个字符覆盖原来的n ap四个字符 
	
	fclose(pf);
	return 0;
} 

程序运行结果
在这里插入图片描述

ftell函数

long int ftell ( FILE * stream );
作用:对于二进制流来说,此函数获取从 文件数据开头位置文件指针此时的位置 之间的字节数
返回值:成功时,返回长度;失败时,返回-1L

测试程序

重新定位文件指针,再获取文件指针的位置

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("BinaryDatas","rb");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	fputs ( "This is an apple." , pf );	//向文件中写入 This is an apple.
	fseek ( pf , 9 , SEEK_SET );		//将指针定位在字符n出,
	int Position = ftell(pf); 	//获取此时距离开头的位置 
	printf("文件指针此时位于距开头%d个字节的位置。\n",Position);
	
	fclose(pf);
	return 0;
} 

程序运行结果

在这里插入图片描述

rewind函数

void rewind ( FILE * stream );
作用:将文件指针定位到文件数据起始位置

测试程序

程序说明:让文件指针指向距离文件起始位置9个字节的地方,再使用rewind函数将文件指针重置定位到文件起始位置

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("BinaryDatas","rb");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");

	fseek ( pf , 9 , SEEK_SET );		//将指针定位在字符n出
	rewind(pf);		//将文件指针定位在文件开头 
	int Position = ftell(pf); 	//获取此时距离开头的位置 
	printf("文件指针此时位于距开头%d个字节的位置。\n",Position);
	
	fclose(pf);
	return 0;
} 

程序运行结果

在这里插入图片描述

文件的结束判定

fgetc函数读取文件时,末尾为EOF
fgets函数读取文件时,末尾为NULL

feof函数

int feof ( FILE * stream );
作用:判断是否到了文件的末尾
返回值:如果到了与流关联的文件结束指示符,则返回非零值。
否则,返回零。

测试程序

程序说明:统计文件中有多少个字节的数据

#include <stdio.h>
int main(){
    
    
	FILE* pf = fopen("BinaryDatas","rb");
	
	if(pf == NULL){
    
    
		printf("打开失败!\n");
		return 1;
	}
	printf("打开或新建成功!\n");
	
	int n = 0; 
	while (fgetc(pf) != EOF) {
    
    
      ++n;
    }
    if (feof(pf)) {
    
    
      puts ("End-of-File reached.");
      printf ("Total number of bytes read: %d\n", n);
    }
    else puts ("End-of-File was not reached.");

	fclose(pf);
	return 0;
} 

程序运行结果
在这里插入图片描述在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45437022/article/details/107234606