关于文件读写的几点学习记录

关于文件读写的几点学习记录

1. 各函数的简单理解

2. 写文件过程中遇到的坑

下面这段代码是找出1~10000之间的素数并保存到文件中。在使用fscanf读取文件的过程中我遇到了几个问题:
1、空文件时如何判断文件结束(文本文件可以直接用feof,对于二进制文件而言可以int ch,读入数据前令ch=fgetc(fp),若ch=EOF,则文件为空)
2、在使用fscanf读数据时发现它的返回值总为-1,即没有分配给它数据,后来发现要再次打开文件,“w”只写,再用“r”打开一遍就行了。
3、fscanf遇到空格、换行停止,坑的一批
4、这代码有问题输到666中途停止
5.写下面这块代码遇到的问题主要是二进制文件的读取,如何跳跃读取(移动指针),算是投机取巧绕过了这个问题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN sizeof(struct LOG)//LEN=56;
int n;
struct LOG{
	char number[20];
	char name[20];
	float score;
	struct LOG *next;
}store[100];
FILE *openfile(char *name,char *openmode);
struct LOG *creat(struct LOG *head);
int input(struct LOG *p);
void write(struct LOG *head);
void read(struct LOG *head);
void rank(struct LOG *head);
int main(){
	struct LOG *head,*p;
	head=creat(head);
	p=head;
	do{
		printf("%s    %s   %.1f\n",p->number,p->name,p->score);
		p=p->next;
	}while(p!=NULL);
	write(head);
	read(head);
	rank(head);
	return 0;
} 
struct LOG *creat(struct LOG *head){
	struct LOG *p1,*p2;
	p1=(struct LOG *)malloc(LEN);
	p2=p1;
	while(input(p1)!=-1){
		n++;
		if(n==1)head=p1;
		p2=p1;
		p1=(struct LOG *)malloc(LEN);
		p2->next=p1;
	}
	free(p1);p2->next=NULL;
	return (head);
}
void write(struct LOG *head){
	FILE *fp;
	struct LOG *p;
	fp=openfile("student.dat","wb+");
	p=head;
	while(p!=NULL){
		fwrite(p,LEN,1,fp);
		p=p->next;
	}
	fclose(fp);
}
void read(struct LOG *head){
	FILE *fp;
	struct LOG *p;
	int i=0,ch=0;
	fp=openfile("student.dat","rb");
	float max=-999,sum=0;
	p=head;
	while(ch!=EOF){                                        //通过读取字符判断是否到达文件末尾 
		fseek(fp,LEN*i++,0);
		fread(p,LEN,1,fp);
		if(p->score>max)max=p->score;
		sum += p->score;
		ch=fgetc(fp);
	}
	printf("max=%.1f\naverage=%.1f\n",max,sum/n);
	fclose(fp);
}
void rank(struct LOG *head){
	FILE *fp,*cfptr;
	struct LOG *p;p=head;
	float mid;
	int j,i=0,mid0;
	char str1[20],str2[20];
	i=0;fp=openfile("student.dat","rb");cfptr=openfile("score.txt","a");
	while(p!=NULL){
		fread(p,LEN,1,fp);
		store[i].score=p->score;
		strcpy(store[i].name,p->name);
		strcpy(store[i].number,p->number);
	//	printf("%f",score_1[i]);
		p=p->next;
		i++;
	}
	for(i=0;i<n;i++){
		for(j=i;j<n;j++){
			if(store[i].score<store[j].score){
				mid=store[i].score;strcpy(str1,store[i].number);strcpy(str2,store[i].name);
				store[i].score=store[j].score;strcpy(store[i].number,store[j].number);strcpy(store[i].name,store[j].name);
				store[j].score=mid;strcpy(store[j].number,str1);strcpy(store[j].name,str2);
			}
		}
	fprintf(cfptr,"%s   %s   %f\n",store[i].number,store[i].name,store[i].score);
	}
	fclose(cfptr);fclose(fp);
}
int input(struct LOG *p){
	printf("Input Number:");scanf("%s",p->number);
	if(strcmp(p->number,"-1")==0)return -1;
	else{
		printf("Input Name:");scanf("%s",p->name);
		printf("Input score:");scanf("%f",&p->score);
	}
	return 0;
}
FILE *openfile(char *name,char *openmode){
	FILE *fp;
	if((fp=fopen(name,openmode))==NULL){
		printf("Can not open the file!\n");
		exit(0);
	}
	return fp;
}
#include <stdio.h>
#include <stdlib.h>
int isprime(int n);
int main(){
	FILE *fp;
	if((fp=fopen("file_date.txt","w"))==NULL){
		printf("Can not open the file!\n");
		exit(0);
	}
	int i,count=0;
	for(i=1;i<10000;i++){
		if(isprime(i)!=-1){
			count++;
			if(count%10!=0)fprintf(fp,"%d\t",i);
			else fprintf(fp,"%d\n",i);
		}
	}
	int n;
	fp=fopen("file_date.txt","rb");
	while(!feof(fp)){
		fscanf(fp,"%d\t",&n);
		printf("%d\n",n);
	}
	fclose(fp);
	return 0;
}
int isprime(int n){
	int i,ret=-1;
	if(n==1)return -1;
	if(n==2||n==3)return 1;
	for(i=2;i<=n/2;i++){
		if(n%i==0)return ret;
	}
	return 1;
}

这是最后的,拷过来纯属无聊

#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct LOG) 

int N=0;//文件里有多少有效数据条 
int count=0;//判断是否是第一次从文件中载入数据 
typedef struct LOG{
	char number[50];
	char name[20];
	float score;
	char department[20];
	struct LOG *next;
} DATE;
struct Order{
	int soilder;
	int ret;
};
int inputchoice(void);
int CountN(FILE *cfptr);
FILE *openfile(char *OpenMode);
struct LOG *AddLog(struct LOG *head,FILE *cfptr);
struct LOG *InputLog(struct LOG *p);
struct LOG *LoadFile(struct LOG **head,FILE *cfptr,struct LOG **p1);//二级指针,在函数内改变指针指向 
struct LOG *ListLog(struct LOG *head,FILE *cfptr);
struct LOG *ListOppointedLog(struct LOG *head,FILE *cfptr);
struct LOG *DeleteLog(struct LOG *head,FILE *cfptr);
struct LOG *ListOrder(struct LOG *head,FILE *cfptr);

int main(){
	int n=2;
	FILE *fp=openfile("r+");
	struct LOG *head=NULL;
	N=CountN(fp);
	printf("%d\n",N);
	while(n!=0){
		n=inputchoice();
		switch (n)
		{
		case 1:
			fp=openfile("a+");
			head=AddLog(head,fp);
			break;
		case 2:
			fp=openfile("r");
			head=ListLog(head,fp);
			break;
		case 3:
			fp=openfile("r");
			head=ListOppointedLog(head,fp);
			break;
		case 4:
			fp=openfile("r+");
			head=DeleteLog(head,fp);
			break;
		case 5:
			fp=openfile("r+");
			head=ListOrder(head,fp);
			break;
		default :printf("Input Error!\n");
		}
	}
	fclose(fp);
	return 0;
}
int inputchoice(){
	int n;
	printf("1-Add new log\n");
	printf("2-List all log\n");
	printf("3-List oppointed log\n");
	printf("4-Delete log\n");
	printf("5-List logs in order\n"); 
	printf("0-exit program!\n");
	scanf("%d",&n);
	return n; 
}
int CountN(FILE *cfptr){
	long n=0;
	fseek(cfptr,0,2);
	n=(ftell(cfptr))/44;
	return n;
} 
FILE *openfile(char *OpenMode){
	FILE *cfptr;
	if((cfptr=fopen("log.txt",OpenMode))==NULL){
		printf("Can not open the file!\n");
		exit(0);
	}
	return cfptr;
}
struct LOG *LoadFile(struct LOG **head,FILE *cfptr,struct LOG **p2){
	int n=0;
	DATE *p,*p1;
	p1=p=(struct LOG*)malloc(LEN);
	rewind(cfptr);
	while(n<N){
		fscanf(cfptr,"%s%s%f%s\n",p->number,p->name,&p->score,p->department);
		//printf("%s   %s   %f\n",p->number,p->name,p->score);
		if(n==0)*head=p;
		else p1->next=p;
		p1=p;
		p=(struct LOG*)malloc(LEN);
		n++;
	}
	p1->next=NULL;free(p);
	*p2=p1;
//	p=head;
//	while(p!=NULL){
//		printf("%s   %s   %f\n",p->number,p->name,p->score);
//		p=p->next;
//	}
	return *p2;
}
struct LOG *AddLog(DATE *head,FILE *cfptr){
	DATE *p,*p1;
	p1=head;
	p=(struct LOG*)malloc(LEN);
	p=InputLog(p);
	//printf("\t%s\t%f\t",p->name,p->score);
	if(N==0){
//		rewind(cfptr);
//		fprintf(cfptr,"Number            Name     Score     Department\n");
		head=p;
		p->next=NULL;
	}
	else{
	if(count==0){
		p1=LoadFile(&head,cfptr,&p1);
		count++;
	}
	p1->next=p;
	p->next=NULL;
}
//	if(count>1){
//		tail->next=p;
//		tail=p;
//		tail->next=NULL;
//	}
	fseek(cfptr,0,2);
	fprintf(cfptr,"%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
	N++;
	return head;
}
struct LOG *ListLog(struct LOG *head,FILE *cfptr){
	DATE *p;
	if(count==0){
	p=LoadFile(&head,cfptr,&p);
	count++;
	}
	p=head;
	int ret=0;
	while(p!=NULL){
		if(ret==0){
		printf("\nNumber            Name     Score     Department\n");
		ret++;
		}
		printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
		p=p->next;
	}
	if(ret==0)printf("There is no log or something wrong!\n");
	return head;
}
struct LOG *ListOppointedLog(struct LOG *head,FILE *cfptr){
	DATE *p;
	if(count==0){
	p=LoadFile(&head,cfptr,&p);
	count++;
	}
	p=head;
	char godmind[20];
	int ret=0,ret1=0;
	printf("please input the name,major or number you want to enquiry\n");
	scanf("%s",godmind);
	if('0'<=godmind[0]&&godmind[0]<='9'){
		while(p!=NULL){
			if(strcmp(godmind,p->number)==0){
				printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
				ret++;
			}
			p=p->next; 
		}
	}
	else {
		while(p!=NULL){
		if(strcmp(godmind,p->name)==0){
			printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
			ret++;
		}
			p=p->next; 
			if(ret>1||ret==0)continue;
			ret1++;
		}
	}
	if(ret1==0&&ret==0){
		p=head;
		while(p!=NULL){
		if(strcmp(godmind,p->department)==0){
			printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
			ret1++;
		}
			p=p->next; 
		}
		}
	if(ret==0&&ret1==0)printf("Not Found!\n");
	return head;
}
struct LOG *DeleteLog(struct LOG *head,FILE *cfptr){
	DATE *p,*p1;
	int n=0;
	char godmind[20];
	printf("Please input the meseage you want to delete(name or number):\n");
	scanf("%s",godmind);
	if(count==0){
	p=LoadFile(&head,cfptr,&p);
	count++;
	}
	p1=p=head;
	if('0'<=godmind[0]&&godmind[0]<='9'){
	while(strcmp(godmind,p->number)!=0&&p->next!=NULL){
		p1=p;
		p=p->next;
	}
	if(strcmp(godmind,p->number)==0){
		if(p==head)head=p->next;
		else p1->next=p->next;
		free(p);
		printf("Delete:%s\n",godmind);
		N--;
	}
	else printf("The list is NULL!\n");
	}
	else {
		while(strcmp(godmind,p->name)!=0&&p->next!=NULL){
		p1=p;
		p=p->next;
	}
	if(strcmp(godmind,p->name)==0){
		if(p==head)head=p->next;
		else p1->next=p->next;
		free(p);
		printf("Delete %s message!\n",godmind);
		N--;
	}
	else printf("The list is NULL!\n");
	}
	p=head;
	cfptr=openfile("w");
	while(p!=NULL){
		fprintf(cfptr,"%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
		p=p->next;
	}
	return head;
}
struct LOG *ListOrder(struct LOG *head,FILE *cfptr){
	DATE *p,*p1;
	int i;
	struct Order *order;
	order=(struct Order *)calloc(N,sizeof(struct Order));
	for(i=0;i<N;i++){
		order[i].soilder=i;
		order[i].ret=0;
	}
	int choice;
	if(count==0){
	p=LoadFile(&head,cfptr,&p);
	count++;
	}
	p1=p=head;
	printf("1-List by score\n2-List by number\n");
	scanf("%d",&choice);
	switch(choice){
		case 1:
			{
			float max=-1;
			int i=0,j;
			while(p!=NULL){
				max=-1;p1=head;j=0;
				while(p1!=NULL){
					if(order[j].ret==0&&p1->score>max){
							max=p1->score;
							order[i].soilder=j;
					}
					j++;
					p1=p1->next;
				}
				order[order[i].soilder].ret=1;
				i++;
				p=p->next;
			}
			for(i=0;i<N;i++){
				p=head;
				for(j=0;j<order[i].soilder;j++)p=p->next;
				printf("%-15s%-10s%-10.1f%-10s\n",p->number,p->name,p->score,p->department);
			}
			break;
		}
		case 2:
			
			break;
		default:printf("Input Error!\n"); 
	}
	return head;
}
struct LOG *InputLog(struct LOG *p){
	printf("Enter the number:");scanf("%s",p->number);
	printf("Enter the name:");scanf("%s",p->name);
	printf("Enter the score:");scanf("%f",&p->score);
	printf("Enter the department:");scanf("%s",p->department);
	printf("Input Finished!\n\n");
	return p;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值