清零操作:
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 109:113 Rocket
Westbrook,38,21,9,9,4
Geogre,38,28,14,2,4
。。。。
其中第一行表示比赛总比分;后面每行表示一个球员的各项统计数据,如第一行表示Westbrook,上场38分钟,得分21分,篮板数为9,助攻数为9,抢断数为4,各项数据间用逗号隔开。
- 要求:
1、读取文件中的各个球员的统计数据
(可以用结构体来存储一个球员的所有数据);
2、用户可以选择不同的统计项来查看数据,如:
得分榜(按球员得分从高到底排序)
助攻榜(按球员助攻从高到底排序)
抢断榜(按球员抢断从高到底排序)
- 根据加权规则计算球员的效率:
得分比重为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"