文件读取基础知识及运用

清零操作:

char str[200] ={0};//清零
memset(str,0,sizeof(str));//清零

读取文件是否存在:

FILE* fp = fopen("文件地址","r");
if(fp == NULL)
{
	printf("打开文件失败。\n");
	return 0;
}

一、用char * fgets ( char * str, int num, FILE * stream )读取文本(字符串来读取):

char str[200];//创建数组
//一行一行读取文本,将每行读取到的都存入数组并输出。
while(fgets(str,200,fp))
{
    printf("%s\n",str);//输出文本内容
}
//fgets(str,200,fp)读完了全部返回NULL

二、用int fgetc( FILE *stream );(用字符来读取文本)返回值:成功时,返回读到的字符,返回的是int类型(实际值是字符)失败或读到文件尾,返回EOF (就是-1):

char ch;//创建字符
while(EOF!=(ch = fgetc(fp)))
{
	printf("%c",ch);//逐个字符输出
}

读取文本大小:

int BUFFSIZE = 1024;
char buf[BUFFSIZE];

memset(buf, 0,sizeof(buf));//关键点就是memset(buf, 0,sizeof(buf));,因为读取的完毕后,并不会为buf字符数组添加\0,所以需要我们亲自给fread添加上尾巴\0,让其能作为字符串正常输出。

//因此我们可以手动添加\0
buf[n] = '\0';//这样就不需要数组清零直接终止

fread (buf, sizeof (char), BUFFSIZE, fp);
printf("%s\n",buf);

重写文本:

fputc('A',fp);//清空重新写A

写入文本:

函数原型 :

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

参数胡说明 :

const void *ptr : 指针指向要写出数据的内存首地址 ;

size_t size : 要写出数据的 基本单元 的字节大小 , 写出单位的大小 ;

size_t nmemb : 要写出数据的 基本单元 的个数 ;

FILE *stream : 打开的文件指针 ;

例子:

cahr * str = "projectawdawd";
fwrite(str,1,strlen(str),fp);

文件指定定位:

函数原型:

int fseek( FILE *stream, long offset, int origin)

函数参数说明:

移动stream文件指针,从origin地址开始,移动offset个偏移字节(正数向后走,负数往回走)。那么,origin参数有如下的取值:

SEEK_SET: 文件开头            SEEK_CUR: 当前位置              SEEK_END: 文件结尾

返回值:成功返回0,失败返回-1

例子:

int num = 456789;
fwrite(&num,sizeof(num),1,fp);

//文件指针定位
fseek(fp,0,SEEK_SET);

int num2;
fread(&num2,1,sizeof(num),fp);
printf("%d\n",num2);
char str[200] = {0};
fseek(fp,5,SEEK_SET);//SEEK_SET是文件开头位置
fread(str,1,100,fp);
printf("%s\n",str);

fseek(fp,-10,SEEK_CUR);//SEEK_CUR是当前指针位置,-10是倒退十个
fread(str,1,100,fp);
printf("%s\n",str);

读取文件最后一行:

//先定位到文件结尾
fseek(fp,-1,SEEK_END);
char ch = 0;
int length = 0;
//读取最后一行文本长度
while(fread(&ch,1,1,fp))
{
    //先读取一个字符再往回走两个字符,从而获取最后一行的长度
	if(ch == '\n')
		break;//如果读取到文件倒数第二行末尾即跳出循环
	fseek(fp,-2,SEEK_CUP);
	length++;
}

fseek(fp,-length,SEEK_END);//指定位置最后
char * buffer = malloc(sizeof(char) * length +1); //创建动态数组
memset(buffer,0,length+1);//清零
fread(buffer,1,length,fp);
printf("%s\n",buffer);

重置到开头并且获取文件当前位置:

rewind(fp);//文件指针重置到开头
fseek(fp,0,SEEK_END);
int nSize = ftell(fp);//ftel文件指针当前位置
printf("文件的大小:%d\n",nSize);

文件读取运用的例子:

题目:

一、用文件存储一场比赛的统计数据,如:

Thunder  109113  Rocket

Westbrook3821994

Geogre38281424

。。。。

其中第一行表示比赛总比分;后面每行表示一个球员的各项统计数据,如第一行表示Westbrook,上场38分钟,得分21分,篮板数为9,助攻数为9,抢断数为4,各项数据间用逗号隔开。

  • 要求:

   1、读取文件中的各个球员的统计数据

(可以用结构体来存储一个球员的所有数据);

   2、用户可以选择不同的统计项来查看数据,如:

得分榜(按球员得分从高到底排序)

助攻榜(按球员助攻从高到底排序)

抢断榜(按球员抢断从高到底排序)

  1. 根据加权规则计算球员的效率:

得分比重为1,篮板比重为2,助攻为2,抢断为5,则球员效率值=加权总得分/总上场时间。如Westbrook的效率值为:

   21*1+9*2+9*2+4*5/38=77/38=2.02

用户选择查看球员效率值后,输出所有上场球员的效率值。

  • 扩展:

   如果有多个文件,每个文件存储一场比赛的统计数据,计算多场比赛的球员数据,注意此时各项数据为多场比赛的平均值,如球员的得分,为多场比赛的每场平均分。

代码:

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

//队伍信息 
struct Team{
	char teamname[10];
	int General_points;
	int ate;
	char are[10];
}team[10],team_2[10];



//球员信息 
struct Count{
		
		char name[10];
		int time;//时间 
		int score;//得分
		int backboard;//篮板数
		int Assisted_number;//助攻数
		int Steal_number; //抢断数
		double efficient_number;//效率值 
}count[10],count_2[10];


int n=-1;
int n2=-1;


//函数声明 
struct Count* inputNBAnumber(struct Count *p,int k); 
struct Count* inputNBAnumber2(struct Count *p,int k) ;
void  score_list(struct Count count[10],int len);
void Assists_list(struct Count count[10],int n);
void Steal_list(struct Count count[10],int n);
void Look(struct Count count[10],int n,int l);
void efficient(struct Count count[10],int n);
void number_NBA();
void number_NBA2();

int main()
{
	FILE* fp = fopen("D:\\Desktop\\球员信息.txt.txt","r+");
	FILE* fp1 = fopen("D:\\Desktop\\第二场.txt","r+");
	if(fp==NULL)
	{
		printf("不能打开该文件\n");
		exit(0);
	}
	if(fp1==NULL)
	{
		printf("不能打开该文件\n");
		exit(0);
	}

	
	char name[10];
	char str[200];
	char ch;
	int l;
	int i=0,j=0,k=0;
	fscanf(fp,"%s%d:%d%s",team[k].teamname,&team[k].General_points,&team[k].ate,team[k].are);
	fscanf(fp1,"%s%d:%d%s",team_2[k].teamname,&team_2[k].General_points,&team_2[k].ate,team_2[k].are);
	number_NBA();
	number_NBA2();
	
	for(k=0;k<n;k++)
	{
		i=0;
	while(EOF!=(ch = fgetc(fp)))
	{
		if(ch==',')
		{
			ch='\0';
			break;
		}
		count[k].name[i]=ch;
		i++;
	}
	fscanf(fp,"%d,%d,%d,%d,%d",&count[k].time,&count[k].score,&count[k].backboard,&count[k].Assisted_number,&count[k].Steal_number);
	}
	
	
	for(k=0;k<n2;k++)
	{
		i=0;
	while(EOF!=(ch = fgetc(fp1)))
	{
		if(ch==',')
		{
			ch='\0';
			break;
		}
		count_2[k].name[i]=ch;
		i++;
	}
	fscanf(fp1,"%d,%d,%d,%d,%d",&count_2[k].time,&count_2[k].score,&count_2[k].backboard,&count_2[k].Assisted_number,&count_2[k].Steal_number);
	}
	
	printf("共有两场,你要选择第几场:");
	scanf("%d",&l);
	if(l==1)
	Look(count,n,l);
	else if(l==2)
	Look(count_2,n2,l);
	else{
		printf("请选择正确的场数!");
		exit(0);
	}
	fclose(fp);
	fclose(fp1);
	return 0;
 } 




void Look(struct Count count[10],int n,int l){
	int choose,add;
	while(1)
	{
	//选择查看
	printf("0.退出系统\n");
	printf("1.查看得分榜\n");
	printf("2.查看助攻榜\n");
	printf("3.查看抢断榜\n");
	printf("4.查看球员效率值\n"); 
	printf("5.增加球员\n");
	printf("输入你的选择:");
		scanf("%d",&choose);
		if(choose==0)
		{
			break;
		}
		switch(choose)
		{
			case 1:
				score_list(count,n);
				break;//得分榜
			case 2:
				Assists_list(count,n);break;//助攻榜
			case 3:
				Steal_list(count,n);break;//抢断榜
			case 4:
				efficient(count,n);break;//效率值
			case 5:
				printf("增加球员人数有:");
				scanf("%d",&add); 
				printf("输入各个球员信息\n");
				if(l==1)
				inputNBAnumber(count,add);
				else
				inputNBAnumber2(count_2,add);break;//增加球员 
			default:
				printf("输入有误,请重新输入!\n"); break;		
		}
	
		//清屏 + 重复输出 
		system("pause");
		system("cls");
	}
}
 
//输入球员信息 
struct Count* inputNBAnumber(struct Count *p,int k)
{
	int i,j;
	char ch[40];
	struct Count *g;
	g=p;
	FILE* fp = fopen("D:\\Desktop\\球员信息.txt.txt","r+");
	for(j=0;j<k;j++)
	{
		i=0;
		while(1)
	    {
	        p->name[i]  = getchar();//逐个输入字符并赋值到字符串中。
	        if(p->name[i] == ',')//输入结束。
	        {
	            p->name[i] = '\0';//赋值结束符。
	            break;//退出循环。
	        }
	        i ++;
	    }
	    scanf("%d,%d,%d,%d,%d",&p->time,&p->score,&p->backboard,&p->Assisted_number,&p->Steal_number);
	    p++;
	}
	for(j=0;j<k;j++)
	{
	
	fseek(fp,0,SEEK_END);
	fprintf(fp,"%s,%d,%d,%d,%d,%d",g->name,g->time,g->score,g->backboard,g->Assisted_number,g->Steal_number);
	g++;
	}
	fclose(fp);
	printf("输入完成!"); 
	return p;
}

struct Count* inputNBAnumber2(struct Count *p,int k)
{
	int i,j;
	char ch[40];
	struct Count *g;
	g=p;
	FILE* fp = fopen("D:\\Desktop\\第二场.txt","r+");
	for(j=0;j<k;j++)
	{
		i=0;
		while(1)
	    {
	        p->name[i]  = getchar();//逐个输入字符并赋值到字符串中。
	        if(p->name[i] == ',')//输入结束。
	        {
	            p->name[i] = '\0';//赋值结束符。
	            break;//退出循环。
	        }
	        i ++;
	    }
	    scanf("%d,%d,%d,%d,%d",&p->time,&p->score,&p->backboard,&p->Assisted_number,&p->Steal_number);
	    p++;
	}
	for(j=0;j<k;j++)
	{
	
	fseek(fp,0,SEEK_END);
	fprintf(fp,"%s,%d,%d,%d,%d,%d",g->name,g->time,g->score,g->backboard,g->Assisted_number,g->Steal_number);
	g++;
	}
	fclose(fp);
	printf("输入完成!"); 
	return p;
}

//得分榜
void  score_list(struct Count count[10],int n)
{
	int i, j, k;
	struct Count team; 
	//冒泡排序 
	for (j = 0; j < n-1; j++)
	{
		for (i = 0; i < n-1 - j; i++)
		{
			if (count[i].score < count[i + 1].score)
			{
				team = count[i];
				count[i] = count[i + 1];
				count[i + 1] = team;
			}
		}
	}
	for(k=0;k<n;k++)
	{
		printf("%s %d\n",count[k].name,count[k].score);
	}
}


//助攻榜
void Assists_list(struct Count count[10],int n)
{
//冒泡排序 
//	int i, j,k;
//	for (j = 0; j < n-1; j++)
//	{
//		for (i = 0; i < n-1 - j; i++)
//		{
//			if (count[i].Assisted_number < count[i + 1].Assisted_number)
//			{
//				team = count[i];
//				count[i] = count[i + 1];
//				count[i + 1] = team;
//			}
//		}
//	}

//插入排序 : 
	int i,j,temp,k;	
	struct Count team;
	for(i=1;i<n;i++)
		if(count[i].Assisted_number<count[i-1].Assisted_number)
		{
			temp=count[i].Assisted_number;
			team = count[i];
			count[i]=count[i-1];
			for(j=i-1;count[j].Assisted_number>temp && j>=0;j--)
				count[j+1]=count[j];
			count[j+1]=team;
		}
		
		
	for(k=0;k<n;k++)
	{
		printf("%s %d\n",count[k].name,count[k].Assisted_number);
	}
}
 
 
//抢断榜
void Steal_list(struct Count count[10],int n)
{
	
	//冒号排序: 
//	int i, j,k;
//	struct Count team;
//	for (j = 0; j < n-1; j++)
//	{
//		for (i = 0; i < n-1 - j; i++)
//		{
//			if (count[i].Steal_number < count[i + 1].Steal_number)
//			{
//				team = count[i];
//				count[i] = count[i + 1];
//				count[i + 1] = team;
//			}
//		}
//	}


//希尔排序: 
int i, j, k, tmp, gap;  // gap 为步长
struct Count team;
    for (gap = n / 2; gap > 0; gap /= 2) { 
    	for (i = 0; i < gap; ++i) { 
	        for (j = i + gap; j < n; j += gap) {
	            tmp = count[j].Steal_number; 
	            k = j-gap; 
	            while (k >= 0 && count[k].Steal_number > tmp) {
				team = count[k];
				count[k] = count[k + gap];
				count[k + gap] = team;
	                k -= gap;
	            }
	            count[k + gap].Steal_number = tmp; 
	        }
	    }
    }
	
	for(k=0;k<n;k++)
	{
		printf("%s %d\n",count[k].name,count[k].Steal_number);
	}
}
 
 
 //效率值
  
  void efficient(struct Count count[10],int n)
  {
  	int i=0;
  	double sum[10];
  	for(i=0;i<n;i++){
  		sum[i]=count[i].score+2*count[i].backboard+2*count[i].Assisted_number+5*count[i].Steal_number;
	  }
	for(i=0;i<n;i++){
		printf("%s %f\n",count[i].name,sum[i]/count[i].time);
	}
   }  
 
 //查看文件球员人数
void number_NBA()
{
	
	FILE* fp = fopen("D:\\Desktop\\球员信息.txt.txt","r+");
	fseek(fp,5,SEEK_SET);
	int i;
	char str[200];
	for(i=0;fgets(str,200,fp);i++)
	{
		n ++;
	}
	fclose(fp);
}
 
 void number_NBA2()
 {
 	FILE* fp = fopen("D:\\Desktop\\第二场.txt","r+");
 	fseek(fp,5,SEEK_SET);
 	int i;
 	char str[200];
 	for(i=0;fgets(str,200,fp);i++)
 	{
 		n2 ++;
	 }
	 fclose(fp);
 }
 
 

文件路径:"D:\Desktop\球员信息.txt.txt"

文件路径: "D:\Desktop\第二场.txt"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值