C语言 文件操作系统 一篇文章足矣 附讲解视频链接

01 FILE 文件的结构体和打开操作

#include<stdio.h>
#include<stdio.h>
#include <cstdlib>
/*
文件指针结构体 FILE 
typedef struct
{
	short level;				 //缓冲区 满或空 的标志
	unsigned flags; 			 //文件状态标志
	char fd; 					//文件描述符
	unsigned char hold;         //如缓冲区无内容则不可读
	short bsize; 			   //缓冲区大小
	unsigned char* buffer;     //数据缓冲区的位置
	unsigned char* curp; 	  //指针当前的指向
	unsigned istemp; 		 //临时文件指示器 
	short token; 			//用于时效性检查
} FILE; 
 
 
	1如何打开文件
		1.1 路径
			1.1.1 相对路径
			1.1.2 绝对路径
		1.2 打开方式 
			r: 只读 read
			w: 写的方式write 如果文件不存在,创建新文件,如果存在,清空文件
			a: 追加 append  在原文件末尾接着
			+: 可读可写
			b: 二进制 binary
			r+ w+ a+
			rb+ wb+ ab+
			rb wb ab
	2 如何关闭文件
		fclose(文件指针) 
*/ 

int main()
{
	//1.要起一个名字在程序中表示文件
	//文件指针表示FILE 
	FILE *MM = NULL;
	
	//2.把名字分配给相应的文件
	//fopen("路径","读写法")
	//错误要记住:stream != NULL 
	MM = fopen("Hello.txt","r");
	
	// 防御性编程,打开为空则创建一个文件 
	if(MM == NULL)
	{
	 	fopen("Hello.txt","w+");  //如果存在,清空文件 
	}
	fclose(MM);
	printf("Hello World\n");
	system("pause");
	return 0;
	
}

02 以字符的读写

#include<stdio.h>
#include<stdio.h>
#include <cstdlib>
#include<string.h> 

/*
	//比较无规律的数据 
	1.以字符方式读写
		file get char
		fgetchar(): 读   
		file put char
		fputc(); 
	2. 以字符串方式读写
	
	//结构化数据: 结构体数据结构 
	3. 格式化读写--->表格数据读写
	4. 以字节流形式读写 
*/ 

int main(){
	FILE *write = fopen("girl.txt","w+");
	//所有的文件操作函数,都包含了移动文件指针 
	char str[] = "I love you,but you don't love me!";
	for(int i=0;i <strlen(str);i++)
	{
		fputc(str[i],write);
	}
	fclose(write);
	
	//char buff[1024] = "";
	FILE *read = fopen("girl.txt","r");
	int ch = fgetc(read); //一个字符一个字符读 
	//文件常识:文件末尾的标记 : EOF
	while(ch!=EOF)
	{
		putchar(ch); //打印读到的文本内容 
		ch = fgetc(read);
	}
	printf("\n");
	 
	
	system("pause");
	return 0;
	
}

03 以字符串的方式打开

#include<stdio.h>
#include<stdio.h>
#include <cstdlib>
#include<string.h> 

/*
	//比较无规律的数据 
	1.以字符方式读写
		file get char
		fgetchar(): 读   
		file put char
		fputc(); 
	2. 以字符串方式读写
		fgets() file get string
		fputs() file put string 
	
	//结构化数据: 结构体数据结构 
	3. 格式化读写--->表格数据读写
	4. 以字节流形式读写 
*/ 

int main(){
	FILE *write = fopen("stirng.txt","a+");
	char str[] = "你好";
	//所有的文件操作函数,都包含了移动文件指针 
	//for(int i=0;i <strlen(str);i++)
	//{
	//	fputc(str[i],write);
	//}
	//以字符串的方式读写 
	fputs(str,write); 
	fclose(write);
	
	FILE *read = fopen("stirng.txt","r");
	//int ch = fgetc(read); //一个字符一个字符读 
	//文件常识:文件末尾的标记 : EOF
	//while(ch!=EOF)
	//{
	//	putchar(ch); //打印读到的文本内容 
	//	ch = fgetc(read);
	//}
	
	//存贮字符串的缓冲区 buff 
	char buff[1024] = "";
	fgets(buff,1024,read); 
	
	//输出一行 文件中只有按了换行才是两行,否则就是一行. 
	puts(buff); 
	
	
	printf("\n");
	system("pause");
	return 0;
	
}

04 dos Copy指令的简单的实现

这是一个命令行程序,需要配置环境变量,讲程序所在目录添加到path路径,功能相当于dos命令下的copy功能
建议看视频配置

#include<stdio.h>
#include<stdio.h>
#include <cstdlib>
#include<string.h> 

/*
	命令行结合文件操作写的案列
	简单实现dos中copy指令
	命令行参数	: 主函数的参数
	文件操作	: 以字符的方式读写 
*/ 
//其中第一个表示参数的个数;第二个参数中argv[0]为自身运行目录路径和程序名,argv[1]指向第一个参数、argv[2]指向第二个参数……  
int main(int argv,char *argc[])
{
	if(argv != 3)
	{
		printf("use myCopy 1.txt 2.txt");
		system("pause");
		return 0;
	}
	else
	{
		//printf("argc[0]=%s \n",argc[0]);
		//printf("argc[1]=%s \n",argc[1]);
		//printf("argc[2]=%s \n",argc[2]);
		printf("覆盖 %s 吗?(Yes/No/All: ",argc[2]);
		int userkey = getchar();
		if(userkey == 'Y' || userkey == 'y')
		{
		 	FILE *file1 = fopen(argc[1],"r");
			FILE *file2 = fopen(argc[2],"w");
			int cNum = fgetc(file1);
			while(cNum != EOF){
				fputc(cNum,file2);
				cNum = fgetc(file1); 
			} 
		 	
		 	fclose(file1);
		 	fclose(file2);
		 	printf("已复制  1个文件\n\n"); 
		 } 
		 else
		 {
		 	printf("已复制  0个文件\n\n"); 
		 }
	}
	system("pause");
	return 0;
	
}

05 格式化读写

fprintf的用法

/*
让我们编译并运行上面的程序,这将在程序目录下创建文件 file.txt,它的内容如下
Hello fprintf in 2020
*/ 
#include <stdio.h>
#include <stdlib.h>

int main()
{
   FILE * fp;
	
   //清空后再写 
   fp = fopen ("fprintf用法.txt", "w+");
   fprintf(fp, "%s %s %s %d", "Hello", "fprintf", "in", 2020);
   
   fclose(fp);
   
   return(0);
}

创建学生结构体,格式化读写

//05 格式化读写 (按照你定义的方式写出数据) 
#include<stdio.h>
#include<stdio.h>
#include <cstdlib>
#include<string.h> 
#include<malloc.h> 
/*
	stdin  键盘:   标准输入
	stdout 显示器: 标准输出 
	文件指针: 自定义文件
	printf(,"%s\t%d\t%d\n","MM",12,13);
	scanf()
	写到目标位置 
		小黑屏写入数据 显示MM  12  13 
			fprintf(stdout,"%s\t%d\t%d\n","MM",12,13);
		目标文件写入 MM  12  13 
			fprintf(FILE *write,,"%s\t%d\t%d\n","MM",12,13); 
	从标准输入 输入a的值 
		fscanf(stdin,"%d",&a);
		fscanf(FILE *read); 
		
	例: 打印文件内容到屏幕 
//	fprintf(stdout,"%s\t%d\t%d\n","MM",12,13);
//	int a;
//	fscanf(stdin,"%d",&a);
//	printf("a=%d\n",a); 
*/
struct student
{
	char name[20];
	int age;
	char sex[6];
};


int main()
{
	//写操作	
	int studentNum = 0;
	printf("请输入学生数: ");
	scanf("%d",&studentNum);
	struct student *array = (struct student*)malloc(sizeof(struct student)*studentNum); 
	FILE *write = fopen("student.txt","w+"); //student.rar写入文件不能打开,不是哈夫曼编码.但是可以记事本打开 
	for(int i=0;i < studentNum;i++)
	{
		printf("请输入第%d为学生的信息: ",i+1);
		scanf("%s%d%s",array[i].name,&array[i].age,array[i].sex); //int 要加&
		fprintf(write,"%s\t%d\t%s\n", array[i].name,array[i].age,array[i].sex);
	}
	fclose(write); 
	 
	
	//读操作 
	FILE *read = fopen("student.txt","r");
	struct student temp; //存储读出来的信息
	//按照什么方式(%s\t%d\t%s\n)写的,按照什么方式读 
	while(fscanf(read,"%s\t%d\t%s\n",temp.name,&temp.age,temp.sex) != EOF) 
	{
		printf("%s\t%d\t%s\n", temp.name,temp.age,temp.sex);
	} 

	
	system("pause");
	return 0;
}

/* 写操作结束后,运行结束后输入数据,生成student.txt文件,按以下格式显示 
张三	18	男
李四	20	男
王五	19	女
*/ 

06 自动朗诵工具

利用VBS文件机制,需要电脑又扬声器驱动

/*
VBS是基于Visual Basic的脚本语言。VBS的全称是:Microsoft Visual Basic Script Edition。
用记事本就可以看到源代码。在没有语法错误的前提下,直接双击左键就可以运行。
但是要注意,因为VBS较为简单可行性强,所以很多人都喜欢利用VBS去写病毒或者整人的代码,
所以在打开VBS之前要确保VBS的安全性和渠道的可信性。
任何一种文本编辑器都可以用来开发VBS,记事本是windows系统自带的,无需专门下载安装,更方便快捷。
*/ 
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <cstdlib>
#include<string.h> 
int main()
{
	char userInput[1024] = "";
	printf("请输入需要朗读的文字: ");
	gets(userInput); 
	//转义字符:一些特殊符号需要用 \+字符 的方式输出 
	FILE *write = fopen("Speak.vbs","w+");
	fprintf(write,"CreateObject(\"SAPI.SpVoice\").Speak(\"%s\")",userInput); 
	fclose(write);
	// 这里需要设置 .vbc文件默认打开方式是用扬声器,就会自动播放 
	// .exe文件是自己做事情,bat文件是系统做事情,system是调用系统进行操作 
	system("Speak.vbs");	   //运行文件 
	system("del Speak.vbs");  //运行完后删除 
	system("pause");
	return 0;
	
}

07 文件指针移动

fwrite()函数的用法

/*
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
	ptr -- 这是指向要被写入的元素数组的指针。
	size -- 这是要被写入的每个元素的大小,以字节为单位。
	nmemb -- 这是元素的个数,每个元素的大小为 size 字节。
	stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。
*/ 

//编译并运行程序,这将创建一个文件 fwrite.txt,它的内容如下: This is fwrite.txt
#include<stdio.h>
 
int main ()
{
   FILE *fp;
   char str[] = "This is fwrite.txt";
 
   fp = fopen( "fwrite.txt" , "w" );
   fwrite(str, sizeof(str) , 1, fp );
 
   fclose(fp);
  
   return(0);
}

/* 可以使用下面的程序查看上面文件的内容:
#include <stdio.h>
 
int main ()
{
   FILE *fp;
   int c;
 
   fp = fopen("file.txt","r");
   while(1)
   {
      c = fgetc(fp);
      if( feof(fp) )
      {
          break ;
      }
      printf("%c", c);
   }
   fclose(fp);
   return(0);
}
*/ 

fread()函数的用法

#include <stdio.h>
#include <string.h>

/*
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
		ptr -- 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
		size -- 这是要读取的每个元素的大小,以字节为单位。
		nmemb -- 这是元素的个数,每个元素的大小为 size 字节。
		stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
	例: fread(temp,3,sizeof(struct student),read); 
*/ 
int main()
{
   FILE *fp;
   char c[] = "This is fread";
   char buffer[20];
 
   /* 打开文件用于读写 */
   fp = fopen("fread().txt", "w+");
 
   /* 写入数据到文件 */
   fwrite(c, strlen(c) + 1, 1, fp);
 
   /* 查找文件的开头 */
   fseek(fp, 0, SEEK_SET);
 
   /* 读取并显示数据 */
   fread(buffer, strlen(c)+1, 1, fp);
   printf("%s\n", buffer);
   fclose(fp);
   
   return(0);
}

文件指针移动

//07 文件指针移动 
#include<stdio.h>
#include<stdio.h>
#include <cstdlib>
#include<string.h> 
#include<malloc.h> 
/*	
	size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
		ptr -- 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
		size -- 这是要读取的每个元素的大小,以字节为单位。
		nmemb -- 这是元素的个数,每个元素的大小为 size 字节。
		stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
	例 fread(temp,3,sizeof(struct student),read); 

	ftell(FILE *read); 检测文件指针移动了多少个字符
	feof(FILE *read); 判断文件指针是否到达文件末尾
	fseek(FILE *res.long size,int mode)
	SEEK_CUR  当前位置 
	SEEK_SET 开始位置 
	SEEK_END 结束位置 
	size: 负:往后 整:往前  长整型(末尾加L)
	fseek(read,0L,SEEK_SET); 
	rewind(FILE *read) 把文件指针移动到文件开始位置  两句话一个意思 
*/
struct student
{
	char name[20];
	int age;
	char sex[6];
};


int main()
{
	//读操作   student.txt里面有3个学生信息 
	FILE *read = fopen("student.txt","r");
	struct student temp[3]; //存储读出来的信息
	fread(temp,3,sizeof(struct student),read); 
	for(int i=0;i < 3;i++)
	{
		printf("%s\t%d\t%s\n", temp[i].name,temp[i].age,temp[i].sex);
	}
	//文件指针到达文件末尾 
	fseek(read,sizeof(struct student),SEEK_SET); //相对于文件开始的位置移动一个结构体长度 
	struct student tempData;
	//普通变量注意用取址符 
	fread(&tempData,1,sizeof(struct student),read);
	printf("第二个人的信息是:\n");
	printf("%s\t%d\t%s\n", tempData.name,tempData.age,tempData.sex); 
	fclose(read); 
	
	printf("\n换行\n"); 
	
	//读取string.txt的信息 
	FILE *readFile = fopen("string.txt","r");
	fseek(readFile,0L,SEEK_END); //测试文件的大小生成合适的字符串大小 
	int length = ftell(readFile);  
	
	//把文件指针移动到开始的位置
	 fseek(readFile,0L,SEEK_SET);
//	char *str = (char *)malloc(sizeof(char)*(length+1));
	char *str = (char *)calloc(length+1,sizeof(char));	
	fgets(str,length,readFile);
	puts(str); //输出读取到的字符 
	fclose(readFile);
	system("pause");
	return 0;
}

08 字节流一次性读写对比05_格式化读写

使用字节流明显方便许多,可以不用for循环写入数据,写完后文档会乱码,但是用字节流读出则不会了

//08 字节流读写数据  输入3组学生数据 
#include<stdio.h>
#include<stdio.h>
#include <cstdlib>
#include<string.h> 
#include<malloc.h> 
/*	
	把buff写入,写count次,每次写 size大小, 写到write指向的文件 
	fwrite(char *buff,int count,size_t size,FILE *write) /
*/
struct student
{
	char name[20];
	int age;
	char sex[6];
};


int main()
{
	//写操作	使用字节流的方式 
	int studentNum = 0;
	printf("请输入学生数: ");
	scanf("%d",&studentNum);
	//根据输入动态生成结构体数目 
	struct student *array = (struct student*)malloc(sizeof(struct student)*studentNum); 
	FILE *write = fopen("student.txt","w+"); //student.rar写入文件不能打开,不是哈夫曼编码.但是可以记事本打开 
	for(int i=0;i < studentNum;i++)
	{
		printf("请输入第%d为学生的信息: ",i+1);
		scanf("%s%d%s",array[i].name,&array[i].age,array[i].sex); //int 要加&
		//fprintf(write,"%s\t%d\t%s\n", array[i].name,array[i].age,array[i].sex);
	}
	//不用格式化,换成字节流的方式,一步到位
	fwrite(array,3,sizeof(struct student)*3,write); 
	fclose(write); 
	 
	/* 
	//读操作 
	FILE *read = fopen("student.txt","r");
	struct student temp; //存储读出来的信息
	//按照什么方式(%s\t%d\t%s\n)写的,按照什么方式读 
	while(fscanf(read,"%s\t%d\t%s\n",temp.name,&temp.age,temp.sex) != EOF) 
	{
		printf("%s\t%d\t%s\n", temp.name,temp.age,temp.sex);
	} 
	fclose(read); 
	*/ 
	FILE *read = fopen("student.txt","r");
	//使用结构体数组一次性全部读出 
	struct student temp[3]; //存储读出来的信息
	fread(temp,3,sizeof(struct student),read);
	for(int i = 0;i < 3;i++)
	{
		printf("%s\t%d\t%s\n", temp[i].name,temp[i].age,temp[i].sex);
	 } 
	system("pause");
	return 0;
}

09 文件重定向

//09 文件重定向 把文件当做屏幕和键盘 (输入和输出) 
/*
	准备input.txt文件  内容为 12 13
	 
	freopen(const char *filename, const char *mode, FILE *stream) 
*/ 
 #include<stdio.h>
 #include<stdlib.h>

int sum(int a,int b)
{
	return a+b;
}
int main()
{
	printf("该文本重定向到 stdout\n");
	freopen("input.txt","r",stdin); //input文件当做输入 
	freopen("output.txt","w",stdout); //output文件当做输出 
	int a,b;
	scanf("%d%d",&a,&b); //input a=12 b=13 
	printf("%d",sum(a,b)); // 25
//	system("pause");
	return 0;
} 

看不懂代码不要慌 讲解视频在这

课程:
https://www.bilibili.com/video/BV1MJ411i7m3?p=2

原创文章 34 获赞 8 访问量 2314

猜你喜欢

转载自blog.csdn.net/qq_41398619/article/details/105862191