C语言文件I/O的学习——谭浩强

一、文件I/O的单字符的入函数–fputs函数、feof函数、fgetc函数

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
    
    
	FILE *fp=fopen("test","w");
	if(fp ==NULL)
	{
    
    
		printf("打开错误!\n");
		exit(0);
	}
	char str[100];
	scanf("%s",str);
	for(int i=0;i<strlen(str);i++)
	{
    
    
		fputc(str[i],fp);
	}
	fclose(fp);   //文件指针关掉才会有数据
	system("cat test\n");  //查看文件
	
	putchar(10);
	FILE *out=fopen("test","r");
	if(out ==NULL)
	{
    
    
		printf("打开错误!\n");
		exit(0);
	}
	char c=fgetc(out);
	while(!feof(out))  //feof函数使用于文件读写的状态识别  是否时文件的结尾
	{
    
    
		putchar(c);
		c=fgetc(out);  //读取一个字节
	}
	putchar(10);
	
	
	fclose(out);
}

运行代码中已经验证了
在这里插入图片描述

二、文件内容排序–I/O函数的应用

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
    
    
	FILE *fileA=fopen("fileA","w");
	FILE *fileB=fopen("fileB","w");
	char str0[100],str1[100];
	printf("请输入文件A的内容:\n");
	scanf("%[^\n]",str0);  //出回车 其他都接收
	for(int i=0;i<strlen(str0);i++)
	{
    
    
		fputc(str0[i],fileA);
	}
	while(getchar()!=10);  //回车的分隔开
	printf("请输入文件B的内容:\n");
	scanf("%[^\n]",str1);
	for(int i=0;i<strlen(str0);i++)
	{
    
    
		fputc(str1[i],fileB);
	}
	fclose(fileA);
	fclose(fileB);
	
	
	FILE *outA=fopen("fileA","r");
	FILE *outB=fopen("fileB","r");
	memset(str0,0,sizeof(str0));
	memset(str1,0,sizeof(str0));  //清空数组
	char *s=str0,c;
	
	c=fgetc(outA);    //读取文件A的内容并保存在str0中
	while(!feof(outA))   
	{
    
    
		*s=c;
		s++;  //指针偏移
		c=fgetc(outA);
	}
	
	s=str1;    //读取文件B的内容
	c=fgetc(outB);
	while(!feof(outB))
	{
    
    
		*s=c;
		s++;
		c=fgetc(outB);
	}
	fclose(outA);
	fclose(outB);
	
	char str2[strlen(str0)+strlen(str1)+1]; //定义变长数组   strlen函数不包括‘\0’的个数
	s=str2;
	*s='\0';  //首先赋值
	
	strcat(str2,str0);  //拼接字符串  拼接在后面
	printf("%s\n",str2);
	strcat(str2,str1);
	printf("%s\n",str2);
	
	// //去除空格
	// s=str2;
	// while(*s!='\0')
	// {
    
    
		// if(*s == ' ')  //空格32
		// {
    
    
			// char *s0=s;
			// while(*s0 != 0)   //前移去除空格
			// {
    
    
				// *s0=*(s0+1);   //前移一位并删除
				// s0++;
			// }
		// }
		// s++;
	// }
	// printf("去除空格后的%s\n",str2);
	
	s=str2;
	for(int i=0;i<strlen(str2)-1;i++)
	{
    
    
		for(int j=i+1;j<strlen(str2);j++)
		{
    
    
			if(s[i]>s[j])  //交换
			{
    
    
				s[i]^=s[j];
				s[j]^=s[i];
				s[i]^=s[j];
			}
		}
	}
	printf("排序后的%s\n",str2);
}

三、文件I/O函数应用–学生成绩记录文件

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

typedef struct
{
    
    
	int  stu_num;
	char name[10];
	float Chinese_score,Maths_score,Englisd_score;
}Stu;
typedef struct node  //一个节点
{
    
    
	Stu data;
	Stu *next;
}*S,s;

//初始化链表
S init_list()
{
    
    
	S p=malloc(sizeof(Stu));
	if(p == NULL)
	{
    
    
		printf("向堆申请内存失败!");
		return NULL;
	}
	p->next=p;  //指向自己
	return p;
}
int head_insert_list(S head,Stu a)
{
    
    	
	S p=malloc(sizeof(Stu));
	if(p == NULL)
	{
    
    
		printf("向堆申请内存失败!");
		return 0;
	}
	*p=*head;
	head->data=a;
	head->next=p;
	
	return 1;
}

void ls_list(S head)
{
    
    
	S p=head;
	while(p->next != head)   //最后一个为空
	{
    
    
		printf("-----------------\n");
		printf("学号:%05d\n",p->data.stu_num);
		printf("姓名:%-9s\n",p->data.name);
		printf("语文:%2.3f\n",p->data.Chinese_score);
		printf("数学:%2.3f\n",p->data.Maths_score);
		printf("英语:%2.3f\n",p->data.Englisd_score);
		printf("\n\n");
		p=p->next; //指针偏移
	}
}

void write_file(S head)
{
    
    
	FILE *fp=fopen("stud","w");
	if(fp == NULL)
	{
    
    
		printf("无法打开文件!\n");
		exit(0);
	}
	char str[200],ch[20],*s;
	float avg=0;
	s=str;
	*s='\0';  //创建一个字符串
	
	strcat(str,"|学号  |姓名   |语文    |数学   |英语   |平均值 \n");
	for(int i=0;i<strlen(str);i++)	fputc(str[i],fp);  //写入文件头
	memset(&str,0,sizeof(str));
	
	S p=head;
	while(p->next != head)   //最后一个为空
	{
    
    
		avg=p->data.Chinese_score+p->data.Chinese_score+p->data.Englisd_score;
		strcat(str,"|");
		
		sprintf(ch,"%05d",p->data.stu_num);
		strcat(str,ch);
		strcat(str,"|");
		memset(&ch,0,sizeof(ch));
		
		sprintf(ch,"%-9s",p->data.name);
		strcat(str,ch);
		strcat(str,"|");
		memset(&ch,0,sizeof(ch));
		
		sprintf(ch,"%2.3f ",p->data.Chinese_score);
		strcat(str,ch);
		strcat(str,"|");
		memset(&ch,0,sizeof(ch));
		
		sprintf(ch,"%2.3f ",p->data.Maths_score);
		strcat(str,ch);
		strcat(str,"|");
		memset(&ch,0,sizeof(ch));
		
		sprintf(ch,"%2.3f ",p->data.Englisd_score);
		strcat(str,ch);
		strcat(str,"|");
		memset(&ch,0,sizeof(ch));
		
		sprintf(ch,"%2.3f ",avg/3);
		strcat(str,ch);
		strcat(str,"|");
		strcat(str,"\n");
		memset(&ch,0,sizeof(ch));
		
		for(int i=0;i<strlen(str);i++)	fputc(str[i],fp);  //写入文件  
		memset(str,0,sizeof(str));  //清空
		
		p=p->next; //指针偏移
	}
	
	fclose(fp);
	
}

void main()
{
    
    
	S head=init_list();
	Stu a;
	int i=0;
	do{
    
    
		printf("\n请输入第%d个学生的信息\n",i+1);
		printf("请输入学号:");
		scanf("%d",&a.stu_num);
		printf("请输入姓名:");
		while(getchar()!=10);  //回车等待,防止下一个字符串跳过
		scanf("%s",a.name);
		printf("请输入语文:");
		scanf("%f",&a.Chinese_score);
		printf("请输入数学:");
		scanf("%f",&a.Maths_score);
		printf("请输入英语:");
		scanf("%f",&a.Englisd_score);
		
		head_insert_list(head,a);
		memset(&a,0,sizeof(a));   //清空数据信息 方便下一次使用
		
	}while(++i < 5);   
	ls_list(head);//展示
	
	write_file(head);
	
	system("cat stud\n");
	
}

四、文件I/O带目录的读写

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
    
    
	FILE *fp=fopen("/mnt/hgfs/code/0218/MK/hello_dir/test12.txt","w+");   //w+可读可写  前面是路径 /不会被清除
	if(fp == NULL)
	{
    
    
		printf("该文件打开不了!\n");
		exit(0);
	}
	char str[3][20],temp[20];
	char *s="/mnt/hgfs/code/0218/MK/hello_dir/test12.txt";  //字符串的  文件路径的处理
	char *s1="C:\\Users\MA\Desktop\code\0218\MK\hello_dir\test12.txt";   //字符串不完整
	char *s2="C:\\Users\\MA\\Desktop\\code\\0218\\MK\\hello_dir\\test12.txt";  /* 这样可以输出 \ */
	printf("Enter string:\n");
	for(int i=0;i<3;i++)	gets(str[i]);   //输入字符串
	for(int i=0;i<3;i++)	fputs(str[i],fp),fputc('\n',fp);  //写入文件
	printf("%s\n",s);
	printf("%s\n",s1);
	printf("%s\n",s2);
	printf("%s\n",str[0]);
	printf("%s\n",str[1]);
	printf("%s\n",str[2]);
}

五、文件I/O的"w+"类似的理解

#include<stdio.h>
#include<string.h>
#include<stdlib.h>     
#define N 3
void main()
{
    
    
	char str[N][20],temp[20];
	for(int i=0;i<N;i++)	gets(str[i]);  //输入字符串
	
	//比较字符串
	for(int i=0;i<N-1;i++)
	{
    
    
		for(int j=i+1;j<N;j++)   //strcmp(s1,s2); 若s1比s2小,则返回负数,相等为0
		{
    
    
			if(strcmp(str[i],str[j]) < 0)   //stri小于strj,返回负数
			{
    
    
				strcpy(temp,str[i]);
				strcpy(str[i],str[j]);
				strcpy(str[j],temp);
			}
		}
	}
	
	//写入文件
	FILE *fp=fopen("wangwu.txt","w+");   //当你使用w+时,读到的时你以前的东西,读不到你刚写的东西,fclose才会保存    w+就是新建文件
	if(fp == NULL)
	{
    
    
		printf("文件打开失败!\n");
		exit(0);
	}
	for(int i=0;i<N;i++)	fputs(str[i],fp),fputc('\n',fp);
	fclose(fp);//保存
	putchar(10);
	
	FILE *fp0=fopen("wangwu.txt","r");   //当你使用w+时,读到的时你以前的东西,读不到你刚写的东西,fclose才会保存
	//读文件
	char c=fgetc(fp0);
	while(!feof(fp0))
	{
    
    
		putchar(c);
		c=fgetc(fp0);
	}
	putchar(10);
	
	fclose(fp);
}

六、文件I/O的fprintf函数和fscanf函数的例子

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
    
    
	char str[200];
	printf("请输入字符串:");
	fgets(str,sizeof(str),stdin);  // stdin是C语言中标准输入流,一般用于获取键盘输入到缓冲区里的东西。接收回车,并以回车结束。
	printf("%s",str);
	
	FILE *fp=fopen("/mnt/hgfs/code/0218/MK/hello_dir/xiaoming.txt","w"); //写
	static int i=180,j=21;
	float k=75.25;
	fprintf(fp,"%d,%d,%lf",i,j,k);  //fprintf的函数调用  写入文件 自带回车
	fprintf(fp,"\n我的身高是%d cm\n我的体重为%lf kg\n",i,k);  //fprintf函数的使用
	i=181,j=22,k=76.25;
	fprintf(fp,"%d,%d,%lf",i,j,k);  //fprintf的函数调用  写入文件 自带回车
	fclose(fp);
	
	FILE *fp0=fopen("/mnt/hgfs/code/0218/MK/hello_dir/xiaoming.txt","r"); //读
	static int i0,j0;
	static float k0;
	fscanf(fp0,"%d,%d,%f",&i0,&j0,&k0);  //fscanf函数的调用  读取文件  从头开始找,规则和格式规划符找到相应的
	printf("%d,%d,%lf\n",i0,j0,k0);  //显示fscanf的输入的形式
	fclose(fp0);
	
	//输入流
	int a,b;
	float c;
	fscanf(stdin,"%d %d %f",&a,&b,&c);    //该函数返回的是格式规划成功的个数
	printf("%d %d %f\n",a,b,c);
}

七、文件I/O的应用–学生管理系统

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct
{
    
    
	char name[15];
	int  age,stu_num;
	float math;
}Stu;

typedef struct node
{
    
    
	Stu 		data;
	struct node *next;
}s,*S;

S new()  //一个new函数   节点的空
{
    
    
	S p=malloc(sizeof(s));
	if(p == NULL)
	{
    
    
		printf("堆内存申请失败!\n");
		return NULL;
	}
	p->next=NULL;
	memset(&p->data,0,sizeof(p->data));  //初始化结构体
	return p;
}

S init_list()  //初始化
{
    
    
	S p=malloc(sizeof(s));
	if(p == NULL)
	{
    
    
		printf("堆内存申请失败!\n");
		return NULL;
	}
	p->next=p;
	return p;
}

int tail_insert_list(S head,Stu a)   //尾插法   第一个为空
{
    
    
	S p=head;
	while(p->next !=head)	p=p->next;   //找到最后一个的数据
	
	
	//要接的最后一个结点的数据处理好
	S p1=new();
	if(p1 == NULL)	return 0;
	p1->data=a;
	p1->next=head;
	
	//接在尾部
	p->next=p1;
	
	return 1;
}

void ls_list(S head)  //遍历列表
{
    
    
	S p=head;
	printf("------ls-----\n");
	do{
    
    
		p=p->next;  //先偏移一次,避免第一个为空的发生
		printf("姓名:%s\n",p->data.name);
		printf("年龄:%d\n",p->data.age);
		printf("学号:%d\n",p->data.stu_num);
		printf("数学成绩:%f\n",p->data.math);
		printf("\n");
	}while(p->next != head);  //最后一个可以被遍历到
	printf("\n-----------\n");
}

Stu scanf_stu()//输入学生信息
{
    
    
	Stu a;
	printf("请输入姓名:");
	scanf("%s",a.name);
	printf("请输入年龄:");
	scanf("%d",&a.age);
	printf("请输入学号:");
	scanf("%d",&a.stu_num);
	printf("请输入数学成绩:");
	scanf("%f",&a.math);
	while(getchar()!=10);  //收到最后的回车
	
	return a;
}

//写入文件
int w_list(S head)
{
    
    
	FILE *fp=fopen("/mnt/hgfs/code/0218/MK/hello_dir/zhaosi.txt","w");
	if(fp == NULL)
	{
    
    
		printf("该文件打不开!\n");
		return 0;
	}
	
	//写入文件
	S p=head;
	do{
    
    
		p=p->next;  //先偏移一次,避免第一个为空的发生
		fprintf(fp,"姓名:%s",p->data.name);   //最后,不带带回车
		fprintf(fp,"年龄:%d",p->data.age);
		fprintf(fp,"学号:%d",p->data.stu_num);
		fprintf(fp,"数学成绩:%f",p->data.math);
		fprintf(fp,"\n--------------\n");
	}while(p->next != head);  //最后一个可以被遍历到
	
	fclose(fp);  //保存文件
	return 1;
}

void main()
{
    
    
	Stu a;
	S head=init_list();
	int i=0;
	do{
    
    
		printf("请输入第%d名学生的信息:\n",i+1);
		a=scanf_stu();
		tail_insert_list(head,a);
		ls_list(head);
	}while(++i<10);
	
	w_list(head); //写入文件
	
	printf("\n查看文件信息:\n\n");
	system("cat zhaosi.txt\n");
}

八、文件I/O的二进制读写

#include<stdio.h>
#define SIZE 10
struct Stu
{
    
    
	char name[15];
	int  num,age;
	char addr[15];
}stu[SIZE],stud[SIZE];

int save();
int cat();
void main()
{
    
    
	int i;
	printf("Plean enter data of students:\n");
	for(i=0;i<SIZE;i++)
		scanf("%s%d%d%s",stu[i].name,&stu[i].num,&stu[i].age,stu[i].addr);
	save();
	cat();
}

int save()
{
    
    
	FILE *fp=fopen("/mnt/hgfs/code/0218/MK/hello_dir/gailun.txt","wb"); //打开文件
	if(fp == NULL)
	{
    
    
		printf("文件打开失败!\n");
		return 0;
	}
	for(int i=0;i<SIZE;i++)
	{
    
    
		char c;
		if(c=fwrite(&stu[i],sizeof(struct Stu),1,fp)!=1)  //fwrite(&stu[i],sizeof(struct Stu),1,fp) 该函数成功返回值可以自己确定的 该函数的错误返回值为1  
			printf("error\n");
	}
	printf("\n");
	fclose(fp);
}

int cat()//读取文件内容
{
    
    
	FILE *fp=fopen("/mnt/hgfs/code/0218/MK/hello_dir/gailun.txt","rb"); //打开文件  读取文件以二进制形式查看
	if(fp == NULL)
	{
    
    
		printf("文件打开失败!\n");
		return 0;
	}
	for(int i=0;i<SIZE;i++)
	{
    
    
		char c;
		if(c=fread(&stud[i],sizeof(struct Stu),1,fp)==1)  //fread(&stu[i],sizeof(struct Stu),1,fp) 该函数成功返回值可以自己确定的 该函数的错误返回值为1  
			printf("%-10s %4d %4d %-15s\n",stud[i].name,stud[i].num,stud[i].age,stud[i].addr);
		printf("%d\t",c);  //打印函数的返回值
	}
	printf("\n");
	fclose(fp);
}

九、文件I/O随机读取文件–remind函数

#include<stdio.h>
//随机读取数据文件
int main()
{
    
    
	FILE *fp1=fopen("/mnt/hgfs/code/0218/MK/hello_dir/file1.dat","w");
	FILE *fp2=fopen("/mnt/hgfs/code/0218/MK/hello_dir/xiaoming.txt","r");
	char c=getc(fp2);   //获取文件的第一个字符
	while(!feof(fp2))
	{
    
    
		putchar(c);
		c=getc(fp2);
	}
	putchar(10);
	rewind(fp2);   //使文件位置标记返回文件开头
	
	
	c=getc(fp2);    //重新读一遍,并写入file1.dat中
	while(!feof(fp2))
	{
    
    
		fputc(c,fp1);  //写入文件
		c=fgetc(fp2);
	}
	fclose(fp1);
	fclose(fp2);
	return 0;
}

十、文件I/O读取偏移–fseek函数

#include<stdio.h>
#include<stdlib.h>
#define SIZE 6
struct Stu
{
    
    
	char name[15];
	char pswd[19];
}stu[SIZE],stud[SIZE];

void main()
{
    
    
	int i;
	FILE *fp=fopen("/mnt/hgfs/code/0218/MK/hello_dir/zhangsan.dat","wb");
	printf("Plean enter students informations:\n");
	for(i=0;i<SIZE;i++)
		scanf("%s %s",stu[i].name,stu[i].pswd);
	for(i=0;i<SIZE;i++)
		fwrite(&stu[i],sizeof(struct Stu),1,fp);  //写入文件
	fclose(fp);   //保存
	
	FILE *fp0=fopen("/mnt/hgfs/code/0218/MK/hello_dir/zhangsan.dat","rb");  //读文件
	if(fp0==NULL)
	{
    
    
		printf("打开文件失败!\n");
		exit(0);
	}
	for(i=0;i<SIZE;i+=2)
	{
    
    
		fseek(fp0,i*sizeof(struct Stu),0);    //开头0中间1结尾2    从头开始偏移i*sizeof(struct Stu)  //偏移
		fread(&stud[i],sizeof(struct Stu),1,fp0);
		printf("%-10s %-15s\n",stud[i].name,stud[i].pswd);
	}
	fclose(fp0);
	printf("查看文件内容!\n");   //.dat文件的数字封装
	system("cat zhangsan.dat\n");
}

十一、文件I/O的函数–feof函数、ferror函数和clearerr函数理解

#include<stdio.h>
//feof函数、ferror函数和clearerr函数
void test_ferror()
{
    
    
	short ch;
	FILE * f1;
	f1 = fopen("test.txt", "w");
	ch = fgetc(f1);
	//注意,我们以 只写 方式打开了文件,但是却尝试向该文件读取一个字符,肯定会操作失败,这时,该文件流就会被设置上错误标识符
	printf("%x\t", ch);
	//这里输出 -1 ,因为当fgetc函数操作失败时返回 EOF,即 -1
	if(ferror(f1)){
    
    
		 //用函数ferror测试文件流是否存在错误标识符
		 printf("Have a error.\n");
		 //结果自然是,所以输出错误信息
	}
	fclose(f1);
}

void test_feof()
{
    
    
	FILE * f1;
	short ch;
	f1 = fopen("utf8.txt", "r");
	while(1)
	{
    
    
		ch = getc(f1);
		//在第三次循环执行getc语句时,由于文件指针已经指向了EOF,所以这次getc函数读取EOF值(-1)之后,如果指针再向后偏移一位,就发现不指向任何有效的位置了(这时指针不会发生偏移了),所以这时文件流会被设置上文件结束标识符
		if (feof(f1))
		{
    
    
			break;
		}
		printf("%x\n", ch);
	}
	fclose(f1);
}

void test_clearerr()
{
    
    
	FILE * f1;
	short ch;
	f1 = fopen("li.bin", "r");
	while(1){
    
    
		ch = getc(f1);
		if (feof(f1))
		{
    
    
			break;
		}
	}
	//上面循环结束之后,文件流已经被设置了文件结束标志
	printf("%x\t", feof(f1)==0);
	//输出 0,说明feof返回非 0 值,即检测到文件已经到结束位置
	clearerr(f1);
	//清除文件流结束标志和错误标志
	printf("%d\n", feof(f1)==0);
	//输出 1,说明feof返回 0 值,即检测到文件没到结束位置,虽然实际上已经到结束位置了
	fclose(f1);
}
void main()
{
    
    
	printf("test_ferror():\n\n");
	test_ferror();
	printf("test_feof():\n\n");
	test_feof();
	printf("test_clearerr():\n\n");
	test_clearerr();
}

记录谭浩强的文件I/O:以上都来自谭浩强的文件I/O,我可能是解答了!!

猜你喜欢

转载自blog.csdn.net/weixin_44763594/article/details/120482276
今日推荐